From d4365a235216d8e93cd07637e343df287ac0f143 Mon Sep 17 00:00:00 2001 From: "Markus M. May" Date: Wed, 10 Jan 2018 22:11:20 +0100 Subject: [PATCH 01/22] Add a unit test for Insulin Plugin --- .../info/nightscout/androidaps/data/Iob.java | 22 +++ .../Insulin/InsulinOrefBasePlugin.java | 31 ++++- .../Insulin/InsulinOrefBasePluginTest.java | 131 ++++++++++++++++++ 3 files changed, 177 insertions(+), 7 deletions(-) create mode 100644 app/src/test/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePluginTest.java diff --git a/app/src/main/java/info/nightscout/androidaps/data/Iob.java b/app/src/main/java/info/nightscout/androidaps/data/Iob.java index ee70699604..762352782b 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/Iob.java +++ b/app/src/main/java/info/nightscout/androidaps/data/Iob.java @@ -12,4 +12,26 @@ public class Iob { activityContrib += iob.activityContrib; return this; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Iob iob = (Iob) o; + + if (Double.compare(iob.iobContrib, iobContrib) != 0) return false; + return Double.compare(iob.activityContrib, activityContrib) == 0; + } + + @Override + public int hashCode() { + int result; + long temp; + temp = Double.doubleToLongBits(iobContrib); + result = (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(activityContrib); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePlugin.java index cbe5f2ff64..b91eefdc9c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePlugin.java @@ -1,5 +1,7 @@ package info.nightscout.androidaps.plugins.Insulin; +import com.squareup.otto.Bus; + import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Iob; @@ -44,38 +46,53 @@ public abstract class InsulinOrefBasePlugin implements PluginBase, InsulinInterf return true; } + public Bus getBus() { + return MainApp.bus(); + } + @Override public double getDia() { double dia = getUserDefinedDia(); if(dia >= MIN_DIA){ return dia; } else { - if((System.currentTimeMillis() - lastWarned) > 60*1000) { - lastWarned = System.currentTimeMillis(); - Notification notification = new Notification(Notification.SHORT_DIA, String.format(MainApp.sResources.getString(R.string.dia_too_short), dia, MIN_DIA), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notification)); - } + sendShortDiaNotification(dia); return MIN_DIA; } } + void sendShortDiaNotification(double dia) { + if((System.currentTimeMillis() - lastWarned) > 60*1000) { + lastWarned = System.currentTimeMillis(); + Notification notification = new Notification(Notification.SHORT_DIA, String.format(this.getNotificationPattern(), dia, MIN_DIA), Notification.URGENT); + this.getBus().post(new EventNewNotification(notification)); + } + } + + public String getNotificationPattern() { + return MainApp.sResources.getString(R.string.dia_too_short); + } + public double getUserDefinedDia() { return MainApp.getConfigBuilder().getProfile() != null ? MainApp.getConfigBuilder().getProfile().getDia() : MIN_DIA; } + public Iob iobCalcForTreatment(Treatment treatment, long time) { + return this.iobCalcForTreatment(treatment, time, 0d); + } + @Override public Iob iobCalcForTreatment(Treatment treatment, long time, double dia) { Iob result = new Iob(); int peak = getPeak(); - if (treatment.insulin != 0d) { long bolusTime = treatment.date; double t = (time - bolusTime) / 1000d / 60d; - double td = getDia()*60; //getDIA() always > 5 + double td = getDia()*60; //getDIA() always >= MIN_DIA double tp = peak; // force the IOB to 0 if over DIA hours have passed diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePluginTest.java new file mode 100644 index 0000000000..de128175cc --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePluginTest.java @@ -0,0 +1,131 @@ +package info.nightscout.androidaps.plugins.Insulin; + +import org.junit.Before; +import org.junit.Test; + +import info.nightscout.androidaps.data.Iob; +import info.nightscout.androidaps.db.Treatment; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Created by triplem on 07.01.18. + */ + +public class InsulinOrefBasePluginTest extends InsulinOrefBasePlugin { + + private int peak; + private double dia; + + private boolean shortDiaNotificationSend; + + @Before + public void setUp() throws Exception { + this.peak = 0; + this.dia = InsulinOrefBasePlugin.MIN_DIA; + this.shortDiaNotificationSend = false; + } + + @Test + public void testGetDia() throws Exception { + assertEquals(InsulinOrefBasePlugin.MIN_DIA, this.getDia(), 0); + + this.dia = InsulinOrefBasePlugin.MIN_DIA + 1; + assertEquals(InsulinOrefBasePlugin.MIN_DIA + 1, this.getDia(), 0); + + this.dia = InsulinOrefBasePlugin.MIN_DIA - 1; + assertEquals(InsulinOrefBasePlugin.MIN_DIA, this.getDia(), 0); + assertTrue(this.shortDiaNotificationSend); + } + + @Test + public void testIobCalcForTreatment() { + Treatment treatment = new Treatment(); + Iob expected = new Iob(); + + assertEquals(expected, this.iobCalcForTreatment(treatment, 0, 0d)); + + this.peak = 30; + long time = System.currentTimeMillis(); + treatment.date = time - 1 * 60 * 60 * 1000; // 1 hour + treatment.insulin = 10d; + + assertEquals(3.92, this.iobCalcForTreatment(treatment, time).iobContrib, 0.1); + } + + + /** + * this method is implemented to allow tests of the iobCalcForTreatment calculation + * @return + */ + @Override + int getPeak() { + return this.peak; + } + + /** + * Userdefined Dia is implemented to allow tests of the getDia method + * + * @return + */ + public double getUserDefinedDia() { + return this.dia; + } + + void sendShortDiaNotification(double dia) { + this.shortDiaNotificationSend = true; + } + + + // the following methods are implemented, but not needed... + @Override + String commentStandardText() { + return null; + } + + @Override + public String getFragmentClass() { + return null; + } + + @Override + public int getId() { + return 0; + } + + @Override + public String getName() { + return null; + } + + @Override + public String getFriendlyName() { + return null; + } + + @Override + public boolean isEnabled(int type) { + return false; + } + + @Override + public boolean isVisibleInTabs(int type) { + return false; + } + + @Override + public void setFragmentEnabled(int type, boolean fragmentEnabled) { + + } + + @Override + public void setFragmentVisible(int type, boolean fragmentVisible) { + + } + + @Override + public int getPreferencesId() { + return 0; + } +} From 8d792a24db9ba081c608e2e448614182e4ddfd07 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 25 Jan 2018 11:21:27 +0100 Subject: [PATCH 02/22] bump 1.57a-dev --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 6ecea2b3e1..169e5c8a5e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -56,7 +56,7 @@ android { targetSdkVersion 23 multiDexEnabled true versionCode 1500 - version "1.57-dev" + version "1.57a-dev" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", generateGitBuild() From e5d20ca9964fcb8cac0c069d97dd7a13ea49c33a Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 26 Jan 2018 17:18:40 +0100 Subject: [PATCH 03/22] ButterKnife to Dana fragment --- .../plugins/Common/SubscriberFragment.java | 10 ++ .../plugins/PumpDanaR/DanaRFragment.java | 113 +++++++----------- 2 files changed, 51 insertions(+), 72 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Common/SubscriberFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Common/SubscriberFragment.java index 74abc837fe..5ca9232646 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Common/SubscriberFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Common/SubscriberFragment.java @@ -2,9 +2,12 @@ package info.nightscout.androidaps.plugins.Common; import android.support.v4.app.Fragment; +import butterknife.Unbinder; import info.nightscout.androidaps.MainApp; abstract public class SubscriberFragment extends Fragment { + protected Unbinder unbinder; + @Override public void onPause() { super.onPause(); @@ -18,5 +21,12 @@ abstract public class SubscriberFragment extends Fragment { updateGUI(); } + @Override public void onDestroyView() { + super.onDestroyView(); + if (unbinder != null) + unbinder.unbind(); + } + + protected abstract void updateGUI(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java index 8ac6bb306b..eaf8a494e5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java @@ -21,6 +21,10 @@ import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import butterknife.Unbinder; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventExtendedBolusChange; @@ -49,27 +53,24 @@ public class DanaRFragment extends SubscriberFragment { } }; - TextView lastConnectionView; - TextView btConnectionView; - TextView lastBolusView; - TextView dailyUnitsView; - TextView basaBasalRateView; - TextView tempBasalView; - TextView extendedBolusView; - TextView batteryView; - TextView reservoirView; - TextView iobView; - TextView firmwareView; - TextView basalStepView; - TextView bolusStepView; - TextView serialNumberView; - TextView queueView; - Button viewProfileButton; - Button historyButton; - Button statsButton; + @BindView(R.id.danar_lastconnection) TextView lastConnectionView; + @BindView(R.id.danar_btconnection) TextView btConnectionView; + @BindView(R.id.danar_lastbolus) TextView lastBolusView; + @BindView(R.id.danar_dailyunits) TextView dailyUnitsView; + @BindView(R.id.danar_basabasalrate) TextView basaBasalRateView; + @BindView(R.id.danar_tempbasal) TextView tempBasalView; + @BindView(R.id.danar_extendedbolus) TextView extendedBolusView; + @BindView(R.id.danar_battery) TextView batteryView; + @BindView(R.id.danar_reservoir) TextView reservoirView; + @BindView(R.id.danar_iob) TextView iobView; + @BindView(R.id.danar_firmware) TextView firmwareView; + @BindView(R.id.danar_basalstep) TextView basalStepView; + @BindView(R.id.danar_bolusstep) TextView bolusStepView; + @BindView(R.id.danar_serialnumber) TextView serialNumberView; + @BindView(R.id.danar_queue) TextView queueView; - LinearLayout pumpStatusLayout; - TextView pumpStatusView; + @BindView(R.id.overview_pumpstatuslayout) LinearLayout pumpStatusLayout; + @BindView(R.id.overview_pumpstatus) TextView pumpStatusView; public DanaRFragment() { } @@ -91,61 +92,10 @@ public class DanaRFragment extends SubscriberFragment { Bundle savedInstanceState) { try { View view = inflater.inflate(R.layout.danar_fragment, container, false); - btConnectionView = (TextView) view.findViewById(R.id.danar_btconnection); - lastConnectionView = (TextView) view.findViewById(R.id.danar_lastconnection); - lastBolusView = (TextView) view.findViewById(R.id.danar_lastbolus); - dailyUnitsView = (TextView) view.findViewById(R.id.danar_dailyunits); - basaBasalRateView = (TextView) view.findViewById(R.id.danar_basabasalrate); - tempBasalView = (TextView) view.findViewById(R.id.danar_tempbasal); - extendedBolusView = (TextView) view.findViewById(R.id.danar_extendedbolus); - batteryView = (TextView) view.findViewById(R.id.danar_battery); - reservoirView = (TextView) view.findViewById(R.id.danar_reservoir); - iobView = (TextView) view.findViewById(R.id.danar_iob); - firmwareView = (TextView) view.findViewById(R.id.danar_firmware); - viewProfileButton = (Button) view.findViewById(R.id.danar_viewprofile); - historyButton = (Button) view.findViewById(R.id.danar_history); - statsButton = (Button) view.findViewById(R.id.danar_stats); - basalStepView = (TextView) view.findViewById(R.id.danar_basalstep); - bolusStepView = (TextView) view.findViewById(R.id.danar_bolusstep); - serialNumberView = (TextView) view.findViewById(R.id.danar_serialnumber); - queueView = (TextView) view.findViewById(R.id.danar_queue); + unbinder = ButterKnife.bind(this, view); - pumpStatusView = (TextView) view.findViewById(R.id.overview_pumpstatus); pumpStatusView.setBackgroundColor(MainApp.sResources.getColor(R.color.colorInitializingBorder)); - pumpStatusLayout = (LinearLayout) view.findViewById(R.id.overview_pumpstatuslayout); - viewProfileButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - FragmentManager manager = getFragmentManager(); - ProfileViewDialog profileViewDialog = new ProfileViewDialog(); - profileViewDialog.show(manager, "ProfileViewDialog"); - } - }); - - historyButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - startActivity(new Intent(getContext(), DanaRHistoryActivity.class)); - } - }); - - statsButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - startActivity(new Intent(getContext(), DanaRStatsActivity.class)); - } - }); - - btConnectionView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - log.debug("Clicked connect to pump"); - ConfigBuilderPlugin.getCommandQueue().readStatus("Clicked connect to pump", null); - } - }); - - updateGUI(); return view; } catch (Exception e) { Crashlytics.logException(e); @@ -154,6 +104,25 @@ public class DanaRFragment extends SubscriberFragment { return null; } + @OnClick(R.id.danar_history) void onHistoryClick() { + startActivity(new Intent(getContext(), DanaRHistoryActivity.class)); + } + + @OnClick(R.id.danar_viewprofile) void onViewProfileClick() { + FragmentManager manager = getFragmentManager(); + ProfileViewDialog profileViewDialog = new ProfileViewDialog(); + profileViewDialog.show(manager, "ProfileViewDialog"); + } + + @OnClick(R.id.danar_stats) void onStatsClick() { + startActivity(new Intent(getContext(), DanaRStatsActivity.class)); + } + + @OnClick(R.id.danar_btconnection) void onBtConnectionClick() { + log.debug("Clicked connect to pump"); + ConfigBuilderPlugin.getCommandQueue().readStatus("Clicked connect to pump", null); + } + @Subscribe public void onStatusEvent(final EventPumpStatusChanged c) { Activity activity = getActivity(); From d634ee7d4b42d756dcb4bb0f0d66494320bfd2d6 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 26 Jan 2018 22:10:27 +0100 Subject: [PATCH 04/22] CS translations --- app/src/main/res/values-cs/strings.xml | 111 ++++++++++++++++++++++++- app/src/main/res/values-de/strings.xml | 4 - app/src/main/res/values-nl/strings.xml | 4 - app/src/main/res/values/strings.xml | 15 ++-- 4 files changed, 117 insertions(+), 17 deletions(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 751d559130..d63122c8a0 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -276,7 +276,7 @@ Zapnout uzavřenou smyčku, zvyšovat max IOB nad 0 a snižovat cílovou glykémii Jeden týden úspěšného používání s běžným příjmem sacharidů Upravit bazály a koeficinty, když bude potřeba a povolit automatickou detekci citlivosti na inzulín - Povolit další fukce pro běžné používání jako AMA + Povolit další funkce pro běžné používání jako AMA Dosaženo limitu Aplikováno %.2fU Smyčka byla zakázána @@ -670,4 +670,113 @@ Fiasp Ultra rychlý - Oref Čekání na konec bolusu. Zbývá %d sek. + Povolit další funkce pro běžné používání jako SMB + Výchozí hodnota: 3 Toto je klíčová hodnota zabezpečení. Říká, že maximánlní nastavitelný bazál je trojnásobkem maximálního denního bazálu. Patrně to nebudete muset měnit, případně si přečtete o tématu \"3x max denní; 4x aktuální\" + Výchozí hodnota: 4 Toto je druhá klíčová hodnota. Říká, že maximální hodnota dočasného bazálu nikdy nebude větší, než čtyřnásobek aktuálního bazálu. Je to proto, aby se lidé nedostali do hodnot nebezpečných bazálu dříve, než pochpí jak OpenAPS pracuje. Znovy vychozí hodnota je 4 a většina lidí ji nidky nebude muset změnit. Pokud nestačí, obvykle je problém někde jinde. + Výchozí hodnota: 1.2 Toto je bezpečnostní nastavení pro detekci sensitivity. Říká, že autosens může zvýšit bazály, snížit ISF a snížit cílovou hodnotu glykémie o 20% + Výchozí hodnota: 0.7 Toto je bezpečnostní nastavení pro detekci sensitivity. Říká, že autosens může snížit bazály, zvýšit ISF a zvýšit cílovou hodnotu glykémie na 70% + Výchozí hodnota: zapnuto Toto nastavení říká, že autosens může měnit také cílové hodnoty glykémií. + Výchozí hodnota: 2 Toto nastavení říká, po jakou část z hodnoty DIA smyčka po bolusu čeká a nereaguje na změny glykémií (zde 3DIA/2 = 1,5h) + Výchozí hodnota: 3.0 Tato hodnota definuje minimální část strávených sacharidů za každých 5 min. Výchozí hodnota je 3mg/dl/5min. Tato hodnota ovlivňuje výpočet COB + Pozor! Za normálních okolností tyto hodnoty nemusíte měnit. Klikněte ZDE, PŘEČTĚTE si informace a UJISTĚTE se, že jim rozumíte dříve, než je začnete měnit. + Interval pro detekci senzitivity [h] + Počet hodin do minulosti pro detekci senzitivity + Jídlo + g + ]]> + kJ + En + Pr + Tuk + Příkaz je právě prováděn + Ovladač pumpy opraven + Pumpa nedostupná + Chybějící glykémie + Používat systémové notifikace pro výstrahy a oznámení + Místní výstrahy + Výstraha při nedostupných glykémiích + Výstraha při nedostupné pumpě + Limit pro nedostupnost pumpy [min] + Urgetní alarm + INFO + Bluetooth + Hlídač BT + Vypne na 1 sek bluetooth v telefonu, pokud se nedaří připojit k pumpě. Může to pomoci u telefonů, které mají problémy s BT + DexcomG5 aplikace (upravená) + Nahrávat data do NS + Nastavení nahrávání z G5 + Upravená aplikace pro stažení + Zobrazovat detailní změny + Zobrazovat rozdíl s jedním desetinným místem navíc + Nepodporovaný firmware v pumpě + Odesílat data do xDrip+ + V xDrip+ vyberte zdroj dat 640g/Eversense + Glykémie z NS + Hodnota bazálu nahrazena minimální možnou + Kalkulace glykémie + Kalkulace bolusového IOB + Kalkulace bazálního IOB + Kalkulace trendu + Kalkulace superbolusu + Ano + No + Pouze kladné + Pouze záporné + Kalkulace COB + Kalkulace s dočasným cílem + Smyčka povolena + APS vybráno + NSClient má povolení k zápisu + Uzavřená smyčka povolena + Maximální IOB nastaveno správně + Glykémie dostupné z vybraného zdroje + Bazální hodnoty nejsou zarovnané na celé hodiny: %s + Chybný profil: %s + Programování pumpy pro bolus + Obnovit + Stav + Aktivita + Žádné spojení %d min + %d%% (%d min zbývá) + Inicializace + Odpojeno + Vypnuto díky chybě + Vypnuto uživatelem + Beží + Rušení dočasného bazálu + Nastavování doč. bazálu (%d%% / %d min) + Bolus (%.1f U) + Obnovování + Nikdy + Požadovaná operace není pumpou podporována + Nebezpečné použití: extended nebo multiwave bolus je aktivní. Pumpa byla vypnuta jen na 6 hodin. Povolené jsou pouze normální bolusy. + Nebezpečné použití: pumpa má nastavený jiný bazální profil než první. Smyčka byla zakázána. Nastavete první profil a znovu načtěte. + Bolus stejné velikosti už byl během poslední minuty požadován. Jako preventivní ochrana před zdvojeným bolusem byla operace zakázána. + Teď + Načítáni historie pumpy + Výstrahy + Nastavení bazálního profilu + V zásobníku je málo inzulínu + Slabá baterie v pumpě + Pumpa hlásí chybu E%d: %s + Pokouším se obnovit spojení + Provádění bolusu a čtení historie selhalo. Zkontrolujte pumpu a zadejte bolus přes péči + Provádění bolusu selhalo. Zdá se, že žádný bolus nebyl podán. Zkontrolujte pumpu a případně pošlete bolus znovu. Jako bezpečnostní opatření podání bolusu není opakováno. + Pouze %.2f U z bolusu %.2f bylo podáno díky chybě. Zkontrolujte pumpu a proveďte nápravu. + Historie + Varování o ukončeném dočasném bazálu bylo potvrzeno. + Varování + Prázdný + Nízký + Normální + Průměr: %3.1f U + Maximum: %3.1f U + Minimum: %3.1f U + Pro přečtení historie chyb dlouze stiskněte tlačítko ALERTS. Varování: může to způsobit chybu, že pumpa bude odmítat všechny připojení a je pak vyžadováno stisknutí tlačítka na pumpě pro obnovení komunikace. + Je vyžadována aktualizace času na pumpě + Pro přečtení celkových denních dávek dlouze stikněte na pumpě tlačítko TDDS. Varování: může to způsobit chybu, že pumpa bude odmítat všechny připojení a je pak vyžadováno stisknutí tlačítka na pumpě pro obnovení komunikace. + Toto načte kompletní historii pumpy a stavy. Všechno v My Data a hodnoty bazálů. Bolusy a dočasné bazály budou přidány do ošetření, pokud neexistují. Může to způsobit duplicity díky nepřesnosti času v pumpě. Neporučuje se pokud používáte smyčku a je určeno pouze pro speciální připady. Varování: může to způsobit chybu, že pumpa bude odmítat všechny připojení a je pak vyžadováno stisknutí tlačítka na pumpě pro obnovení komunikace. + Opravdu chcete přečíst historii z pumpy a nést důsledky z toho vyplývající? + Nedostatek inzulínu pro takovýto bolus + Chyba spuštění extended bolusu diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 33a4b1bed4..265c6c63ac 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -711,9 +711,6 @@ Aktivität %d%% (%d Min. verbleibend) Keine Verbindung zur Pumpe seit %d Min. - Bolusabgabe gestoppt - Bolusabgabe wird abgebrochen - Fehlerprotokol Status Keine Verbindung zur Pumpe Gestoppt (Benutzer) @@ -727,7 +724,6 @@ Bitte starte dein Telefon neu oder starte AndroidAPS in den System-Einstellungen neu. Andernfalls wird AndroidAPS nicht protokolliert (wichtig zum Nachverfolgen und Verifizieren, dass der Algorithmus korrekt funktioniert) TBR %.1f IE (%s, %s) - Nutze System-Benachrichtigungen für Alarme Ein gleich großer Bolus wurde in der letzten Minute angefordert. Dies ist nicht zulässig, um ungewollte Doppelboli zu verhindern und vor eventuellen Bugs zu schützen. Historie wird gelesen Basalratenprofil wird aktualisiert diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index e40e9c2b59..8a822898df 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -676,16 +676,12 @@ Bedieningen via horloge Ampull leeg Wachten op koppelen van de pomp - Storingen Wijzigingen van profiel Bluetooth Voeding Waarschuwing bij niet bereikbare pomp Een bolus met dezelfde hoeveelheid was gevraagd binnen de minuut. Om accidentiële of door bugs veroorzaakte dubbele bolussen te vermijden is deze bolus geannuleerd - estopt Bolus toediening wordt Vet - Bolus toediening gestopt - Gebruik systeem notificaties voor waarschuwingen Toon gedetaillieerde delta Niet ondersteune pomp firmware DexcomG5 App (aangepast) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ef4478c208..c983b8b3e9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -268,7 +268,6 @@ DIA [h] Duration of Insulin Activity Failed to update basal profile - Errors Reload Uploading E bolus @@ -452,9 +451,9 @@ Model: %02X Protocol: %02X Code: %02X Profile max_daily_safety_multiplier - Default value: 3\nThis is a key OpenAPS safety cap. What this does is limit your basals to be 3x (in this people) your biggest basal rate. You likely will not need to change this, but you should be aware that’s what is discussed about “3x max daily; 4x current” for safety caps. + Default value: 3 This is a key OpenAPS safety cap. What this does is limit your basals to be 3x (in this people) your biggest basal rate. You likely will not need to change this, but you should be aware that’s what is discussed about “3x max daily; 4x current” for safety caps. current_basal_safety_multiplier - Default value: 4\nThis is the other half of the key OpenAPS safety caps, and the other half of “3x max daily; 4x current” of the safety caps. This means your basal, regardless of max basal set on your pump, cannot be any higher than this number times the current level of your basal. This is to prevent people from getting into dangerous territory by setting excessively high max basals before understanding how the algorithm works. Again, the default is 4x; most people will never need to adjust this and are instead more likely to need to adjust other settings if they feel like they are “running into” this safety cap. + Default value: 4 This is the other half of the key OpenAPS safety caps, and the other half of “3x max daily; 4x current” of the safety caps. This means your basal, regardless of max basal set on your pump, cannot be any higher than this number times the current level of your basal. This is to prevent people from getting into dangerous territory by setting excessively high max basals before understanding how the algorithm works. Again, the default is 4x; most people will never need to adjust this and are instead more likely to need to adjust other settings if they feel like they are “running into” this safety cap. autosens_max Default value: 1.2\nThis is a multiplier cap for autosens (and soon autotune) to set a 20% max limit on how high the autosens ratio can be, which in turn determines how high autosens can adjust basals, how low it can adjust ISF, and how low it can set the BG target. autosens_min @@ -464,9 +463,9 @@ bolussnooze_dia_divisor Default value: 2\nBolus snooze is enacted after you do a meal bolus, so the loop won’t counteract with low temps when you’ve just eaten. The example here and default is 2; so a 3 hour DIA means that bolus snooze will be gradually phased out over 1.5 hours (3DIA/2). min_5m_carbimpact - Default value: 3.0\nThis is a setting for default carb absorption impact per 5 minutes. The default is an expected 3mg/dl/5min. This affects how fast COB are decayed, and how much carb absorption is assumed in calculating future predicted BG, when BG is falling more than expected, or not rising as much as expected. + Default value: 3.0 This is a setting for default carb absorption impact per 5 minutes. The default is an expected 3mg/dl/5min. This affects how fast COB are decayed, and how much carb absorption is assumed in calculating future predicted BG, when BG is falling more than expected, or not rising as much as expected. Attention!\nNormally you do not have to change these values below. Please CLICK HERE and READ the text and make sure you UNDERSTAND it before change any of these values. - http://openaps.readthedocs.io/en/latest/docs/walkthrough/phase-3/beyond-low-glucose-suspend.html + http://openaps.readthedocs.io/en/latest/docs/walkthrough/phase-3/beyond-low-glucose-suspend.html Only numeric digits are allowed. Only numeric digits within the range %1$s - %2$s are allowed. The field must not be empty @@ -781,7 +780,7 @@ Switches off the phone\'s bluetooth for one second if no connection to the pump is possible. This may help on some phones where the bluetooth stack freezes. DexcomG5 App (patched) Upload BG data to NS - dexcomg5_nsupload + dexcomg5_nsupload G5 upload settings Customized APK for download Show detailed delta @@ -818,7 +817,7 @@ Activity No connection for %d min %d%% (%d min remaining) - %.1f U (%s, %s) + %.1f U (%s, %s) Initializing Disconnected Suspended due to error @@ -852,7 +851,7 @@ Pump clock update needed History Warning - This will read the full history and state of the pump. Everything in \"My Data\" and the basal rate. Boluses and TBRs will be added to Treatments if they don\'t already exist. This can cause entries to be duplicated because the pump\'s time is imprecise. Using this when normally looping with the pump is highly discouraged and reserved for special circumstances. If you still want to do this, long press this button again.\n\nWARNING: this can trigger a bug which causes the pump to reject all connection attempts and requires pressing a button on the pump to recover and should therefore be avoided. + This will read the full history and state of the pump. Everything in My Data and the basal rate. Boluses and TBRs will be added to Treatments if they don\'t already exist. This can cause entries to be duplicated because the pump\'s time is imprecise. Using this when normally looping with the pump is highly discouraged and reserved for special circumstances. If you still want to do this, long press this button again. WARNING: this can trigger a bug which causes the pump to reject all connection attempts and requires pressing a button on the pump to recover and should therefore be avoided. Are you really sure you want to read all pump data and take the consequences of this action? TBR CANCELLED warning was confirmed Bolus delivery failed. It appears no bolus was delivered. To be sure, please check the pump to avoid a double bolus and then bolus again. To guard against bugs, boluses are not automatically retried. From ce3c888246164fc8c2df855250a3fcc7918fb011 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 27 Jan 2018 13:40:19 +0100 Subject: [PATCH 05/22] add RO language --- app/src/main/res/values-ro/strings.xml | 4 ++++ app/src/main/res/values/arrays.xml | 2 ++ app/src/main/res/values/strings.xml | 1 + 3 files changed, 7 insertions(+) create mode 100644 app/src/main/res/values-ro/strings.xml diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml new file mode 100644 index 0000000000..ab81436cc5 --- /dev/null +++ b/app/src/main/res/values-ro/strings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index ad6a2e1166..660f6ee00e 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -20,6 +20,7 @@ @string/el_lang @string/it_lang @string/ko_lang + @string/ro_lang @string/ru_lang @string/sv_lang @@ -33,6 +34,7 @@ el it ko + ro ru sv diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c983b8b3e9..554b7f759f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -209,6 +209,7 @@ Spanish Greek Italian + Romanian Russian Swedish Max U/hr a Temp Basal can be set to From d4fe03ac307cc94360df12d7ab28564a3e2158aa Mon Sep 17 00:00:00 2001 From: Radoslav Radev Date: Sat, 27 Jan 2018 16:12:51 +0200 Subject: [PATCH 06/22] Bg translation --- app/src/main/res/values-bg/strings.xml | 61 +++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 312b02b69a..5839ae79ce 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -445,7 +445,6 @@ По подразбиране: 2\nBolus snooze се активира след като поставите болус за основно хранене, така Loop няма да пуснка/намаля базалите веднага след като сте се хранили. Примерът тук е с 2; така при 3 часа DIA това ще означава че bolus snooze ще бъде внимателно изместен 1.5 часа (3DIA/2). По подразбиране: 3.0\nТова е настройка на количеството на покачване на КЗ при усвояване на въглехидратите за всеки 5 минути. По подразбиране 3мг/дл/5мин. Това се отразява на това колко бързо се усвояват COB според алгоритъма, и как това се отразява в предвиждането на КЗ, когато тя не се покачва или пада с различен темп от очакваното. Внимание! Обикновено Вие не трябва да променяте тези стойности. Моля НАТИСНЕТЕ ТУК, прочетете текста и бъдете сигурни, че го РАЗБИРАТЕ преди да направите каквито и да е промени! - http://openaps.readthedocs.io/en/latest/docs/walkthrough/phase-3/beyond-low-glucose-suspend.html Позволени са само числа Позволени са числа между %1$s - %2$s Полето не може да бъде празно @@ -677,4 +676,64 @@ Настройки на часовник Задаване временни цели и въвеждане Лечения от часовник Android wear Контролиране от часовник + Closed Loop е позволен + Чете историята на помпата + Настройва базалният профил + Опитва се да възстанови връзката + Доставянето на болуса и проверката на историята на помпата са неуспешни, моля, проверете помпата и ако е доставен болус го добавете като запис през Careportal + Модифицирано приложение за изтегляне + Задайте стъпка на базала 0.01 Е/ч + Dexcom G5 приложение (модифицирано) + Качвай данните за КЗ в NS + В xDrip+ изберете 640g/Eversense за източник на данни + Изпращай данни за КЗ към xDrip+ + Аларма при липса на данни за КЗ + Аларма при недостъпна помпа + Командата се изпълнява в момента + Грешка при доставяне на удължен болус + Храна + Има данни за КЗ от избрания източник + ИНФО + Локални аларми + Loop разрешен + Максимален IOB е зададен правилно + Базалната стойност е заместена от минимално подържаната + Липсват данни за КЗ + Само отрицателни + Не + ]]> + КЗ от NS + NSClient има права за запис + Калкулиране на базален IOB + Калкулиране на КЗ + Калкулиране на Болус IOB + Калкулиране на COB + Калкулиране суперболус + Калкулиране на временни цели + Калкулиране на тенденция КЗ + Само положителни + Обработва се събитие + Помпата е недостъпна + Лимит за недостъпна помпа [мин] + Драйверът за помпата е коригиран + Оставащ инсулин + Стартира доставка на болус + Неподдържан фърмуер на помпата + Спешна аларма + Очаква края на болуса. Остават %d сек. + Показвай делта с още един десетичен знак + Показвай подробна делта + Да + Невалиден профил: %s + En + Използвай системни известия за аларми и съобщения + Внимание + Минимум: %3.1f U + Максимум: %3.1f U + Средно: %3.1f U + Нормално + Ниско + Няма достатъчно инсулин в резервоара + Празен + Обнови From 76d606fddfd8beef58998297dbe0390e027b4827 Mon Sep 17 00:00:00 2001 From: warstar2187 Date: Sun, 28 Jan 2018 10:51:09 +0900 Subject: [PATCH 07/22] Update strings.xml --- app/src/main/res/values-ko/strings.xml | 193 ++++++++++++++++++++----- 1 file changed, 153 insertions(+), 40 deletions(-) diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 3b62dffeab..ab55cbf83a 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -129,9 +129,9 @@ APS 모드 Closed Loop Open Loop - Loop 비활성화됨 - Loop 비활성화하기 - Loop 활성화하기 + Loop 중지됨 + Loop 중지하기 + Loop 실행하기 새로운 제안이 있습니다 지원하지 않는 NSClient 버전입니다 지원하지 않는 Nightscout 버전입니다 @@ -183,7 +183,7 @@ 임시기초주입 확장식사주입 Nightscout 버전: - 보내기 + 전송하기 Missing 사용 보이기 @@ -252,13 +252,12 @@ Finger Sensor Manual - 임시 목표 - 임시 목표 취소 + 임시목표 + 임시목표 취소 DanaR 프로파일 설정 인슐린활동시간(DIA) [h] Duration of Insulin Activity 기초주입 프로파일 갱신 실패 - 과거기록 새로고침 업로드중 E bolus @@ -313,7 +312,7 @@ Loop가 중지중입니다. Loop가 실행중입니다. %.2f limited to %.2f - 값 %s 은 하드리밋(Hard Limit)를 벗어났습니다 + %s값이 하드리밋(Hard Limit)를 벗어났습니다 원격 기초주입설정이 허가되지 않았습니다 원격 명령이 허가되지 않았습니다 기초주입 %.2fU/h 을 실행하려면 %s 를 입력하고 답장하세요 @@ -398,7 +397,7 @@ NS에서 이벤트 새로고침 Eating Soon Activity - Remove record: + 기록 삭제: DanaR 통계 누적 일총량 지수가중 일총량 @@ -437,7 +436,7 @@ 단순델타값 대신 단기평균델타값을 항상 사용합니다. xDrip의 혈당데이터에 노이즈가 심할경우 유용합니다. 고급 설정 - Model: %02X Protocol: %02X Code: %02X + 모델: %02X 프로토콜: %02X 코드: %02X 프로파일 기본값: 3\n이 값은 중요한 OpenAPS 안전장치입니다. 이 값의 역할은 펌프에 설정되어 있는 최대기초주입량보다 3배를 초과할 수 없게 제한하는 것입니다. 이 값을 변경할 필요는 없을 것이지만, 안전을 위해 "3x max daily; 4x current"이 의미하는 바를 알고 있어야 합니다. 기본값: 4\n이 값은 "3x max daily; 4x current"의 나머지 절반에 해당하는 또 다른 중요한 OpenAPS 안전장치입니다. 이 값은 펌프에 설정된 최대기초주입량과 관계없이, 설정된 현재시간의 기초주입량에 이 값을 곱한 양을 초과할 수 없게됩니다. 이는 알고리즘의 작동 방식을 이해하기 전에 과도하게 높은 최대 기본을 설정하여 위험한 상황에 빠지지 않도록 보호하기 위한 것입니다. 다시한번, 기본 값은 4배인 것을 알아두세요; 일반적으로 이것을 조정할 필요는 전혀 없으며, 대신 이 안전장치를 변경해야할것처럼 생각이 된다면, 다른 설정을 변경해야 할 가능성이 더 큽니다. @@ -453,8 +452,8 @@ 필수 입력 항목입니다. 폰번호가 유효하지 않습니다 SMS폰번호가 유효하지 않습니다 - Copy To Clipboard - Copied to clipboard + 클립보드에 복사 + 클립보드에 복사되었습니다 로그 보기 보정 혈당 보정 @@ -476,7 +475,7 @@ 연결끊기중 실행중 가상펌프 설정 - Upload status to NS + NS에 상태 업로드하기 잘못된 비밀번호 설정 비밀번호 설정 잠금해제 @@ -484,7 +483,7 @@ 내장 NSClient NSCI URL: - Autoscroll + 자동스크롤 Restart 내장 NSClient Nightscout URL @@ -500,13 +499,13 @@ Show queue Queue: Status: - Paused + 일시중지 Clear log NSCLIENT이 쓰기 권한이 없습니다. 잘못된 API secret인지 확인해보세요 웨어 설정 IOB 자세하게 보여주기 워치페이스에 IOB를 식사주입IOB와 기초주입IOB로 나누어서 보여줍니다. - not successful - please check phone + 성공하지 못했습니다. 폰을 확인하세요 알수없음 나이 어린이 @@ -519,7 +518,7 @@ %s needs battery optimalization whitelisting for proper performance Loop 일시중지 일시중지중 (%d분) - Superbolus (%d분) + 수퍼 식사주입 (%d분) Loop 메뉴 1시간동안 Loop 일시중지 2시간동안 Loop 일시중지 @@ -530,24 +529,24 @@ 2시간동안 펌프 일시중지 3시간동안 펌프 일시중지 10시간동안 펌프 일시중지 - 재시작 + 재실행 기간이 잘못되었습니다. - Loop가 일시중지되었습니다. - Loop가 재시작되었습니다. + Loop가 일시중지 되었습니다. + Loop가 재실행 되었습니다. 15분 추이 COB - Superbolus + 수퍼 식사주입 앱시작을 NS에 기록하기 설정을 적용하기위해 앱을 종료합니다. 다나Rv2 인슐린 Fast Acting Insulin - Novorapid, Novolog, Humalog - Fiasp + 노보래피드, 휴마로그, 에피드라 + 피아스프(Fiasp) INS Fast Acting Insulin Prolonged - 마법사에서 Superbolus 활성화하기 - 마법사에서 Superbolus 기능을 활성화합니다. 어떤 기능인지 확실히 알기전까지 활성화 하지 마세요. 제대로 알지 못하고 사용하면 일슐린이 과다 주입될 수 있습니다! + 마법사에서 수퍼 식사주입 활성화하기 + 마법사에서 수퍼 식사주입 기능을 활성화합니다. 어떤 기능인지 확실히 알기전까지 활성화 하지 마세요. 제대로 알지 못하고 사용하면 일슐린이 과다 주입될 수 있습니다! IOB COB PRE @@ -584,15 +583,15 @@ 펌프배터리사용기간 펌프 배터리 교체 알람 옵션 - Urgent high - High - Low - Urgent low + 위험 고혈당 + 고혈당 + 저혈당 + 위험 저혈당 Currently set to %f - Stale data - Urgent stale data - Stale data threshold [min] - Urgent stale data threshold [min] + 누락 데이터 + 위험 누락 데이터 + 누락 데이터 기준값[분] + 위험 누락 데이터 기준값[분] autosens 시간 [h] 민감도를 감지하기 위해 계산될 총 시간 (탄수화물 흡수 시간은 제외됩니다.) SEN @@ -604,8 +603,8 @@ Uploader 민감도 감지 SENS - Sensitivity Oref0 - Sensitivity AAPS + 민감도 Oref0 + 민감도 AAPS 흡수 설정 식사 최대 흡수 시간 [h] 식사로 섭취한 탄수화물이 모두 흡수될기까지 예상되는 시간 @@ -621,7 +620,7 @@ 화면 잠금 잠금 Autosense 기능을 켜면 모든 섭취된 탄수화물양을 입력하십시오. 그렇지 않으면 탄수화물 편차(deviations)가 민감도 변화로 잘못 인식될것입니다!! - Sensitivity WeightedAverage + 민감도 가중평균 OK Cancel needs to be activated to send values to the pump! @@ -637,13 +636,13 @@ 펌프 Basal value [U/h] Duration [min] - IOB Curve Peak Time - Peak Time [min] + IOB 커브 피크 시간 + 피크 시간[분] Free-Peak Oref Rapid-Acting Oref Ultra-Rapid Oref - "DIA of %s too short - using %s instead!" - ACTIVATE PROFILE + "DIA %s는 너무 짧습니다. 대신 %s을 사용하세요!" + 프로파일 활성화하기 Date INVALID 펌프연동 대기중 @@ -678,4 +677,118 @@ 워치로 작동하기 임시목표와 관리입력을 워치로 설정합니다. 연결시간초과 + 음식 + g + ]]> + kJ + En + Pr + Fat + ]]> + 식사주입 종료를 기다리고 있습니다. %d초 남았습니다. + 이벤트 처리중 + 식사주입을 시작합니다. + 명령을 지금 실행합니다. + 펌프 드라이버가 수정되었습니다. + 펌프에 연결할 수 없습니다. + 혈당 읽기가 누락되었습니다. + raise_urgent_alarms_as_android_notification + 경고와 알림시 시스템 알림 사용하기 + enable_pump_unreachable_alert + enable_missed_bg_readings + 자체 경고 기능 + 혈당 데이터 누락시 경고하기 + 펌프와 연결불가시 경고하기 + 펌프 연결불가 기준시간[분] + pump_unreachable_threshold + missed_bg_readings_threshold + 긴급 알람 + 정보 + bt_watchdog + bt_watchdog_last + 블루투스 + 블루투스 감시기능 + 펌프에 연결이 되지 않을때 폰의 블루투스를 1초간 껐다 켭니다. 블루투스 스택이 정지되는 일부폰에 이 기능이 도움이 됩니다. + (패치된) DexcomG5 앱 + NS에 혈당데이터 업로드하기 + dexcomg5_nsupload + G5업로드 세팅 + Customized APK for download + 델타(혈당증분값) 자세히 보여주기 + 소수점 한자리 더 추가된 델타 보여주기 + 지원되지 않는 펌프 펌웨어 + 혈당 데이터를 xDrip+에 전송하기 + dexcomg5_xdripupload + xDrip+ 데이터 소스에서 640g/Eversense을 선택하세요 + NSClient BG + 지원되는 최소값으로 기초주입량이 대체되었습니다. + 혈당 계산 + 식사주입 IOB 계산 + 기초주입 IOB 계산 + 추세계산 + 수퍼 식사주입 계산 + + 아니오 + 양수만 + 음수만 + COB 계산 + 임시목표 계산 + Loop 활성화됨 + APS 선택됨 + NSClient가 쓰기권한이 있습니다 + Closed 모드가 활성화됨 + 최대 IOB가 바르게 설정됨 + 선택한 소스에서 혈당이 들어옵니다. + 기초주입값이 시간단위로 설정되지 않았습니다: %s + 유효하지 않은 프로파일: %s + Programming pump for bolusing + Refresh + TDDS + State + Activity + No connection for %d min + %d%% (%d min remaining) + %.1f U (%s, %s) + Initializing + Disconnected + Suspended due to error + Suspended by user + Running + Cancelling TBR + Setting TBR (%d%% / %d min) + Bolusing (%.1f U) + Refreshing + Never + Requested operation not supported by pump + Unsafe usage: extended or multiwave boluses are active. Loop mode has been set to low-suspend only 6 hours. Only normal boluses are supported in loop mode + Unsafe usage: the pump uses a different basal rate profile than the first. The loop has been disabled. Select the first profile on the pump and refresh. + A bolus with the same amount was requested within the last minute. To prevent accidental double boluses and to guard against bugs this is disallowed. + Now + Reading pump history + 펌프 이력 + Alerts + Setting basal profile + Pump cartridge level is low + Pump battery is low + The pump is showing the error E%d: %s + To read the pump\'s error history, long press the ALERTS button\n\nWARNING: this can trigger a bug which causes the pump to reject all connection attempts and requires pressing a button on the pump to recover and should therefore be avoided. + To read the pump\'s TDD history, long press the TDDS button\n\nWARNING: this can trigger a bug which causes the pump to reject all connection attempts and requires pressing a button on the pump to recover and should therefore be avoided. + Minimum: %3.1f U + Average: %3.1f U + Maximum: %3.1f U + Low + Empty + Normal + Pump clock update needed + History + Warning + This will read the full history and state of the pump. Everything in My Data and the basal rate. Boluses and TBRs will be added to Treatments if they don\'t already exist. This can cause entries to be duplicated because the pump\'s time is imprecise. Using this when normally looping with the pump is highly discouraged and reserved for special circumstances. If you still want to do this, long press this button again. WARNING: this can trigger a bug which causes the pump to reject all connection attempts and requires pressing a button on the pump to recover and should therefore be avoided. + Are you really sure you want to read all pump data and take the consequences of this action? + TBR CANCELLED warning was confirmed + Bolus delivery failed. It appears no bolus was delivered. To be sure, please check the pump to avoid a double bolus and then bolus again. To guard against bugs, boluses are not automatically retried. + Only %.2f U of the requested bolus of %.2f U was delivered due to an error. Please check the pump to verify this and take appropriate actions. + Delivering the bolus and verifying the pump\'s history failed, please check the pump and manually create a bolus record using the Careportal tab if a bolus was delivered. + Recovering from connection loss + Not enough insulin for bolus left in reservoir + 확장식사주입 에러 From c297ce88bba4c993e401ae84704357744567517f Mon Sep 17 00:00:00 2001 From: warstar2187 Date: Sun, 28 Jan 2018 11:01:56 +0900 Subject: [PATCH 08/22] Update strings.xml --- app/src/main/res/values-ko/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index ab55cbf83a..8fcb3ca676 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -305,13 +305,14 @@ 필요하면 기초주입과 비율을 조절하고, auto-sens를 활성화한다. 평소의 탄수화물을 입력하면서 1주일동안 낮시간대에 loop를 성공적으로 사용해본다. AMA(Advanced Meal Assist)같은 낮시간대를 위한 추가적인 기능들을 실행하여 본다. + 낮시간대에 SMB(Super Micro Bolus)같은 추가기능을 활성화해 사용해본다. 허용된 제한값에 도달하였습니다 프로파일이 선택되지 않았습니다 Loop가 중지되었습니다. Loop가 실행되었습니다. Loop가 중지중입니다. Loop가 실행중입니다. - %.2f limited to %.2f + %.2f, %.2f으로 제한됨 %s값이 하드리밋(Hard Limit)를 벗어났습니다 원격 기초주입설정이 허가되지 않았습니다 원격 명령이 허가되지 않았습니다 From f54452515bdc1c4405fa3fbde6676a5d73e79c2e Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 28 Jan 2018 23:29:33 +0100 Subject: [PATCH 09/22] KO language cleanup --- app/src/main/res/values-ko/strings.xml | 67 ++------------------------ 1 file changed, 4 insertions(+), 63 deletions(-) diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 8fcb3ca676..98471c491f 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -385,13 +385,13 @@ MM640g 연속 알림 OLD DATA - %d분전 - %dmin ago + %d분전 + %dmin ago Local Profile OpenAPS AMA Short avg. delta Long avg. delta - Array of %d elements.\nActual value: + Array of %d elements.\nActual value: Autosens 정보 Script debug AMA autosens 기능 사용하기 @@ -449,7 +449,7 @@ 주의!\n보통의 경우 아래의 값을 변경하면 안됩니다. 이 값들을 변경하기 전에 반드시 이곳을 클릭하고 글을 정독해서 확실하게 이해를 하여야 합니다. http://openaps.readthedocs.io/en/latest/docs/walkthrough/phase-3/beyond-low-glucose-suspend.html 숫자만 입력가능합니다. - 이 범위(%1$s - %2$s)안에 해당하는 숫자만 입력가능합니다. + 이 범위(%1$s - %2$s)안에 해당하는 숫자만 입력가능합니다. 필수 입력 항목입니다. 폰번호가 유효하지 않습니다 SMS폰번호가 유효하지 않습니다 @@ -516,7 +516,6 @@ Glimp Device does not appear to support battery optimization whitelisting! 권한을 허용하세요. - %s needs battery optimalization whitelisting for proper performance Loop 일시중지 일시중지중 (%d분) 수퍼 식사주입 (%d분) @@ -693,35 +692,25 @@ 펌프 드라이버가 수정되었습니다. 펌프에 연결할 수 없습니다. 혈당 읽기가 누락되었습니다. - raise_urgent_alarms_as_android_notification 경고와 알림시 시스템 알림 사용하기 - enable_pump_unreachable_alert - enable_missed_bg_readings 자체 경고 기능 혈당 데이터 누락시 경고하기 펌프와 연결불가시 경고하기 펌프 연결불가 기준시간[분] - pump_unreachable_threshold - missed_bg_readings_threshold 긴급 알람 정보 - bt_watchdog - bt_watchdog_last 블루투스 블루투스 감시기능 펌프에 연결이 되지 않을때 폰의 블루투스를 1초간 껐다 켭니다. 블루투스 스택이 정지되는 일부폰에 이 기능이 도움이 됩니다. (패치된) DexcomG5 앱 NS에 혈당데이터 업로드하기 - dexcomg5_nsupload G5업로드 세팅 Customized APK for download 델타(혈당증분값) 자세히 보여주기 소수점 한자리 더 추가된 델타 보여주기 지원되지 않는 펌프 펌웨어 혈당 데이터를 xDrip+에 전송하기 - dexcomg5_xdripupload xDrip+ 데이터 소스에서 640g/Eversense을 선택하세요 - NSClient BG 지원되는 최소값으로 기초주입량이 대체되었습니다. 혈당 계산 식사주입 IOB 계산 @@ -742,54 +731,6 @@ 선택한 소스에서 혈당이 들어옵니다. 기초주입값이 시간단위로 설정되지 않았습니다: %s 유효하지 않은 프로파일: %s - Programming pump for bolusing - Refresh - TDDS - State - Activity - No connection for %d min - %d%% (%d min remaining) - %.1f U (%s, %s) - Initializing - Disconnected - Suspended due to error - Suspended by user - Running - Cancelling TBR - Setting TBR (%d%% / %d min) - Bolusing (%.1f U) - Refreshing - Never - Requested operation not supported by pump - Unsafe usage: extended or multiwave boluses are active. Loop mode has been set to low-suspend only 6 hours. Only normal boluses are supported in loop mode - Unsafe usage: the pump uses a different basal rate profile than the first. The loop has been disabled. Select the first profile on the pump and refresh. - A bolus with the same amount was requested within the last minute. To prevent accidental double boluses and to guard against bugs this is disallowed. - Now - Reading pump history 펌프 이력 - Alerts - Setting basal profile - Pump cartridge level is low - Pump battery is low - The pump is showing the error E%d: %s - To read the pump\'s error history, long press the ALERTS button\n\nWARNING: this can trigger a bug which causes the pump to reject all connection attempts and requires pressing a button on the pump to recover and should therefore be avoided. - To read the pump\'s TDD history, long press the TDDS button\n\nWARNING: this can trigger a bug which causes the pump to reject all connection attempts and requires pressing a button on the pump to recover and should therefore be avoided. - Minimum: %3.1f U - Average: %3.1f U - Maximum: %3.1f U - Low - Empty - Normal - Pump clock update needed - History - Warning - This will read the full history and state of the pump. Everything in My Data and the basal rate. Boluses and TBRs will be added to Treatments if they don\'t already exist. This can cause entries to be duplicated because the pump\'s time is imprecise. Using this when normally looping with the pump is highly discouraged and reserved for special circumstances. If you still want to do this, long press this button again. WARNING: this can trigger a bug which causes the pump to reject all connection attempts and requires pressing a button on the pump to recover and should therefore be avoided. - Are you really sure you want to read all pump data and take the consequences of this action? - TBR CANCELLED warning was confirmed - Bolus delivery failed. It appears no bolus was delivered. To be sure, please check the pump to avoid a double bolus and then bolus again. To guard against bugs, boluses are not automatically retried. - Only %.2f U of the requested bolus of %.2f U was delivered due to an error. Please check the pump to verify this and take appropriate actions. - Delivering the bolus and verifying the pump\'s history failed, please check the pump and manually create a bolus record using the Careportal tab if a bolus was delivered. - Recovering from connection loss - Not enough insulin for bolus left in reservoir 확장식사주입 에러 From 4cef8db54b67cbe4ec0cf967d5c6e4a6a07358fc Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 29 Jan 2018 11:24:03 +0100 Subject: [PATCH 10/22] Dana plugin refactoring --- .../PumpDanaR/AbstractDanaRPlugin.java | 557 ++++++++++++++++++ .../plugins/PumpDanaR/DanaRFragment.java | 7 +- .../plugins/PumpDanaR/DanaRPlugin.java | 543 +---------------- .../plugins/PumpDanaR/DanaRPump.java | 4 +- .../plugins/PumpDanaR/SerialIOThread.java | 9 +- .../PumpDanaR/comm/MsgInitConnStatusTime.java | 2 +- .../PumpDanaR/comm/MsgSettingBasal.java | 2 +- .../PumpDanaR/comm/MsgSettingMeal.java | 9 +- .../AbstractDanaRExecutionService.java | 225 +++++++ .../services/AbstractSerialIOThread.java | 13 + .../services/DanaRExecutionService.java | 286 ++------- .../PumpDanaRKorean/DanaRKoreanPlugin.java | 546 +---------------- .../PumpDanaRKorean/SerialIOThread.java | 9 +- .../comm/MsgInitConnStatusTime_k.java | 2 +- .../comm/MsgSettingBasal_k.java | 2 +- .../services/DanaRKoreanExecutionService.java | 255 ++------ .../plugins/PumpDanaRS/DanaRSPlugin.java | 12 +- .../PumpDanaRS/services/DanaRSService.java | 6 +- .../plugins/PumpDanaRv2/DanaRv2Plugin.java | 485 +-------------- .../plugins/PumpDanaRv2/SerialIOThread.java | 9 +- .../PumpDanaRv2/comm/MsgCheckValue_v2.java | 4 +- .../services/DanaRv2ExecutionService.java | 250 ++------ 22 files changed, 1030 insertions(+), 2207 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractSerialIOThread.java diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java new file mode 100644 index 0000000000..ea47303fb6 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java @@ -0,0 +1,557 @@ +package info.nightscout.androidaps.plugins.PumpDanaR; + +import android.support.annotation.Nullable; + +import org.json.JSONException; +import org.json.JSONObject; +import org.slf4j.Logger; + +import java.util.Date; +import java.util.Objects; + +import info.nightscout.androidaps.BuildConfig; +import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.data.ProfileStore; +import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.db.ExtendedBolus; +import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.interfaces.ConstraintsInterface; +import info.nightscout.androidaps.interfaces.DanaRInterface; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.ProfileInterface; +import info.nightscout.androidaps.interfaces.PumpDescription; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; +import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractDanaRExecutionService; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.Round; + +/** + * Created by mike on 28.01.2018. + */ + +public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface { + protected Logger log; + + protected boolean mPluginPumpEnabled = false; + protected boolean mPluginProfileEnabled = false; + protected boolean mFragmentPumpVisible = true; + + protected AbstractDanaRExecutionService sExecutionService; + + protected DanaRPump pump = DanaRPump.getInstance(); + protected boolean useExtendedBoluses = false; + + public PumpDescription pumpDescription = new PumpDescription(); + + @Override + public String getFragmentClass() { + return DanaRFragment.class.getName(); + } + + // Plugin base interface + @Override + public int getType() { + return PluginBase.PUMP; + } + + @Override + public String getNameShort() { + String name = MainApp.sResources.getString(R.string.danarpump_shortname); + if (!name.trim().isEmpty()) { + //only if translation exists + return name; + } + // use long name as fallback + return getName(); + } + + @Override + public boolean isEnabled(int type) { + if (type == PluginBase.PROFILE) return mPluginProfileEnabled && mPluginPumpEnabled; + else if (type == PluginBase.PUMP) return mPluginPumpEnabled; + else if (type == PluginBase.CONSTRAINTS) return mPluginPumpEnabled; + return false; + } + + @Override + public boolean isVisibleInTabs(int type) { + if (type == PluginBase.PROFILE || type == PluginBase.CONSTRAINTS) return false; + else if (type == PluginBase.PUMP) return mFragmentPumpVisible; + return false; + } + + @Override + public boolean canBeHidden(int type) { + return true; + } + + @Override + public boolean hasFragment() { + return true; + } + + @Override + public boolean showInList(int type) { + return type == PUMP; + } + + @Override + public void setFragmentEnabled(int type, boolean fragmentEnabled) { + if (type == PluginBase.PROFILE) + mPluginProfileEnabled = fragmentEnabled; + else if (type == PluginBase.PUMP) + mPluginPumpEnabled = fragmentEnabled; + // if pump profile was enabled need to switch to another too + if (type == PluginBase.PUMP && !fragmentEnabled && mPluginProfileEnabled) { + setFragmentEnabled(PluginBase.PROFILE, false); + setFragmentVisible(PluginBase.PROFILE, false); + NSProfilePlugin.getPlugin().setFragmentEnabled(PluginBase.PROFILE, true); + NSProfilePlugin.getPlugin().setFragmentVisible(PluginBase.PROFILE, true); + } + } + + @Override + public void setFragmentVisible(int type, boolean fragmentVisible) { + if (type == PluginBase.PUMP) + mFragmentPumpVisible = fragmentVisible; + } + + @Override + public boolean isSuspended() { + return pump.pumpSuspended; + } + + @Override + public boolean isBusy() { + if (sExecutionService == null) return false; + return sExecutionService.isConnected() || sExecutionService.isConnecting(); + } + + // Pump interface + @Override + public PumpEnactResult setNewBasalProfile(Profile profile) { + PumpEnactResult result = new PumpEnactResult(); + + if (sExecutionService == null) { + log.error("setNewBasalProfile sExecutionService is null"); + result.comment = "setNewBasalProfile sExecutionService is null"; + return result; + } + if (!isInitialized()) { + log.error("setNewBasalProfile not initialized"); + Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(notification)); + result.comment = MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet); + return result; + } else { + MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); + } + if (!sExecutionService.updateBasalsInPump(profile)) { + Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.sResources.getString(R.string.failedupdatebasalprofile), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(notification)); + result.comment = MainApp.sResources.getString(R.string.failedupdatebasalprofile); + return result; + } else { + MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); + MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE)); + Notification notification = new Notification(Notification.PROFILE_SET_OK, MainApp.sResources.getString(R.string.profile_set_ok), Notification.INFO, 60); + MainApp.bus().post(new EventNewNotification(notification)); + result.success = true; + result.enacted = true; + result.comment = "OK"; + return result; + } + } + + @Override + public boolean isThisProfileSet(Profile profile) { + if (!isInitialized()) + return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS + if (pump.pumpProfiles == null) + return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS + int basalValues = pump.basal48Enable ? 48 : 24; + int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60; + for (int h = 0; h < basalValues; h++) { + Double pumpValue = pump.pumpProfiles[pump.activeProfile][h]; + Double profileValue = profile.getBasal((Integer) (h * basalIncrement)); + if (profileValue == null) return true; + if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) { + log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); + return false; + } + } + return true; + } + + @Override + public Date lastDataTime() { + return new Date(pump.lastConnection); + } + + @Override + public double getBaseBasalRate() { + return pump.currentBasal; + } + + @Override + public void stopBolusDelivering() { + if (sExecutionService == null) { + log.error("stopBolusDelivering sExecutionService is null"); + return; + } + sExecutionService.bolusStop(); + } + + @Override + public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) { + PumpEnactResult result = new PumpEnactResult(); + ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); + percent = configBuilderPlugin.applyBasalConstraints(percent); + if (percent < 0) { + result.isTempCancel = false; + result.enacted = false; + result.success = false; + result.comment = MainApp.instance().getString(R.string.danar_invalidinput); + log.error("setTempBasalPercent: Invalid input"); + return result; + } + if (percent > getPumpDescription().maxTempPercent) + percent = getPumpDescription().maxTempPercent; + TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); + if (runningTB != null && runningTB.percentRate == percent && !enforceNew) { + result.enacted = false; + result.success = true; + result.isTempCancel = false; + result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); + result.duration = pump.tempBasalRemainingMin; + result.percent = pump.tempBasalPercent; + result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); + result.isPercent = true; + if (Config.logPumpActions) + log.debug("setTempBasalPercent: Correct value already set"); + return result; + } + int durationInHours = Math.max(durationInMinutes / 60, 1); + boolean connectionOK = sExecutionService.tempBasal(percent, durationInHours); + if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) { + result.enacted = true; + result.success = true; + result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); + result.isTempCancel = false; + result.duration = pump.tempBasalRemainingMin; + result.percent = pump.tempBasalPercent; + result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); + result.isPercent = true; + if (Config.logPumpActions) + log.debug("setTempBasalPercent: OK"); + return result; + } + result.enacted = false; + result.success = false; + result.comment = MainApp.instance().getString(R.string.tempbasaldeliveryerror); + log.error("setTempBasalPercent: Failed to set temp basal"); + return result; + } + + @Override + public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { + ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); + insulin = configBuilderPlugin.applyBolusConstraints(insulin); + // needs to be rounded + int durationInHalfHours = Math.max(durationInMinutes / 30, 1); + insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep); + + PumpEnactResult result = new PumpEnactResult(); + ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); + if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) { + result.enacted = false; + result.success = true; + result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); + result.duration = pump.extendedBolusRemainingMinutes; + result.absolute = pump.extendedBolusAbsoluteRate; + result.isPercent = false; + result.isTempCancel = false; + if (Config.logPumpActions) + log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin); + return result; + } + boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours); + if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) { + result.enacted = true; + result.success = true; + result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); + result.isTempCancel = false; + result.duration = pump.extendedBolusRemainingMinutes; + result.absolute = pump.extendedBolusAbsoluteRate; + result.bolusDelivered = pump.extendedBolusAmount; + result.isPercent = false; + if (Config.logPumpActions) + log.debug("setExtendedBolus: OK"); + return result; + } + result.enacted = false; + result.success = false; + result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly); + log.error("setExtendedBolus: Failed to extended bolus"); + return result; + } + + @Override + public PumpEnactResult cancelExtendedBolus() { + PumpEnactResult result = new PumpEnactResult(); + ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); + if (runningEB != null) { + sExecutionService.extendedBolusStop(); + result.enacted = true; + result.isTempCancel = true; + } + if (!pump.isExtendedInProgress) { + result.success = true; + result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); + if (Config.logPumpActions) + log.debug("cancelExtendedBolus: OK"); + return result; + } else { + result.success = false; + result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly); + log.error("cancelExtendedBolus: Failed to cancel extended bolus"); + return result; + } + } + + @Override + public void connect(String from) { + if (sExecutionService != null) { + sExecutionService.connect(); + pumpDescription.basalStep = pump.basalStep; + pumpDescription.bolusStep = pump.bolusStep; + } + } + + @Override + public boolean isConnected() { + return sExecutionService != null && sExecutionService.isConnected(); + } + + @Override + public boolean isConnecting() { + return sExecutionService != null && sExecutionService.isConnecting(); + } + + @Override + public void disconnect(String from) { + if (sExecutionService != null) sExecutionService.disconnect(from); + } + + @Override + public void stopConnecting() { + if (sExecutionService != null) sExecutionService.stopConnecting(); + } + + @Override + public void getPumpStatus() { + if (sExecutionService != null) sExecutionService.getPumpStatus(); + } + + @Override + public JSONObject getJSONStatus() { + if (pump.lastConnection + 5 * 60 * 1000L < System.currentTimeMillis()) { + return null; + } + JSONObject pumpjson = new JSONObject(); + JSONObject battery = new JSONObject(); + JSONObject status = new JSONObject(); + JSONObject extended = new JSONObject(); + try { + battery.put("percent", pump.batteryRemaining); + status.put("status", pump.pumpSuspended ? "suspended" : "normal"); + status.put("timestamp", DateUtil.toISOString(pump.lastConnection)); + extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION); + extended.put("PumpIOB", pump.iob); + if (pump.lastBolusTime.getTime() != 0) { + extended.put("LastBolus", pump.lastBolusTime.toLocaleString()); + extended.put("LastBolusAmount", pump.lastBolusAmount); + } + TemporaryBasal tb = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); + if (tb != null) { + extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis())); + extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date)); + extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes()); + } + ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); + if (eb != null) { + extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate()); + extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date)); + extended.put("ExtendedBolusRemaining", eb.getPlannedRemainingMinutes()); + } + extended.put("BaseBasalRate", getBaseBasalRate()); + try { + extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName()); + } catch (Exception e) { + } + + pumpjson.put("battery", battery); + pumpjson.put("status", status); + pumpjson.put("extended", extended); + pumpjson.put("reservoir", (int) pump.reservoirRemainingUnits); + pumpjson.put("clock", DateUtil.toISOString(new Date())); + } catch (JSONException e) { + log.error("Unhandled exception", e); + } + return pumpjson; + } + + @Override + public String deviceID() { + return pump.serialNumber; + } + + @Override + public PumpDescription getPumpDescription() { + return pumpDescription; + } + + /** + * DanaR interface + */ + + @Override + public PumpEnactResult loadHistory(byte type) { + return sExecutionService.loadHistory(type); + } + + /** + * Constraint interface + */ + + @Override + public boolean isLoopEnabled() { + return true; + } + + @Override + public boolean isClosedModeEnabled() { + return true; + } + + @Override + public boolean isAutosensModeEnabled() { + return true; + } + + @Override + public boolean isAMAModeEnabled() { + return true; + } + + @Override + public boolean isSMBModeEnabled() { + return true; + } + + @SuppressWarnings("PointlessBooleanExpression") + @Override + public Double applyBasalConstraints(Double absoluteRate) { + double origAbsoluteRate = absoluteRate; + if (pump != null) { + if (absoluteRate > pump.maxBasal) { + absoluteRate = pump.maxBasal; + if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit) + log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h"); + } + } + return absoluteRate; + } + + @SuppressWarnings("PointlessBooleanExpression") + @Override + public Integer applyBasalConstraints(Integer percentRate) { + Integer origPercentRate = percentRate; + if (percentRate < 0) percentRate = 0; + if (percentRate > getPumpDescription().maxTempPercent) + percentRate = getPumpDescription().maxTempPercent; + if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit)) + log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%"); + return percentRate; + } + + @SuppressWarnings("PointlessBooleanExpression") + @Override + public Double applyBolusConstraints(Double insulin) { + double origInsulin = insulin; + if (pump != null) { + if (insulin > pump.maxBolus) { + insulin = pump.maxBolus; + if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit) + log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U"); + } + } + return insulin; + } + + @Override + public Integer applyCarbsConstraints(Integer carbs) { + return carbs; + } + + @Override + public Double applyMaxIOBConstraints(Double maxIob) { + return maxIob; + } + + @Nullable + @Override + public ProfileStore getProfile() { + if (pump.lastSettingsRead == 0) + return null; // no info now + return pump.createConvertedProfile(); + } + + @Override + public String getUnits() { + return pump.getUnits(); + } + + @Override + public String getProfileName() { + return pump.createConvertedProfileName(); + } + + // Reply for sms communicator + public String shortStatus(boolean veryShort) { + String ret = ""; + if (pump.lastConnection != 0) { + Long agoMsec = System.currentTimeMillis() - pump.lastConnection; + int agoMin = (int) (agoMsec / 60d / 1000d); + ret += "LastConn: " + agoMin + " minago\n"; + } + if (pump.lastBolusTime.getTime() != 0) { + ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n"; + } + if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { + ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n"; + } + if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { + ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n"; + } + if (!veryShort) { + ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n"; + } + ret += "IOB: " + pump.iob + "U\n"; + ret += "Reserv: " + DecimalFormatter.to0Decimal(pump.reservoirRemainingUnits) + "U\n"; + ret += "Batt: " + pump.batteryRemaining + "\n"; + return ret; + } + // TODO: daily total constraint + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java index eaf8a494e5..1ca54a7eb6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java @@ -21,6 +21,8 @@ import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Date; + import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -120,6 +122,7 @@ public class DanaRFragment extends SubscriberFragment { @OnClick(R.id.danar_btconnection) void onBtConnectionClick() { log.debug("Clicked connect to pump"); + DanaRPump.getInstance().lastConnection = 0; ConfigBuilderPlugin.getCommandQueue().readStatus("Clicked connect to pump", null); } @@ -181,8 +184,8 @@ public class DanaRFragment extends SubscriberFragment { @Override public void run() { DanaRPump pump = DanaRPump.getInstance(); - if (pump.lastConnection.getTime() != 0) { - Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime(); + if (pump.lastConnection != 0) { + Long agoMsec = System.currentTimeMillis() - pump.lastConnection; int agoMin = (int) (agoMsec / 60d / 1000d); lastConnectionView.setText(DateUtil.timeString(pump.lastConnection) + " (" + String.format(MainApp.sResources.getString(R.string.minago), agoMin) + ")"); SetWarnColor.setColor(lastConnectionView, agoMin, 16d, 31d); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java index 3a11ebe0a6..9a0be55897 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java @@ -5,69 +5,30 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; -import android.support.annotation.Nullable; import com.squareup.otto.Subscribe; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; -import java.util.Objects; - -import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventPreferenceChange; -import info.nightscout.androidaps.interfaces.ConstraintsInterface; -import info.nightscout.androidaps.interfaces.DanaRInterface; -import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpDescription; -import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; -import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; -import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; import info.nightscout.androidaps.plugins.PumpDanaR.services.DanaRExecutionService; -import info.nightscout.utils.DateUtil; -import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.Round; import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. */ -public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface { - private static Logger log = LoggerFactory.getLogger(DanaRPlugin.class); - - @Override - public String getFragmentClass() { - return DanaRFragment.class.getName(); - } - - private static boolean fragmentPumpEnabled = false; - private static boolean fragmentProfileEnabled = false; - private static boolean fragmentPumpVisible = true; - - private static DanaRExecutionService sExecutionService; - - - private static DanaRPump pump = DanaRPump.getInstance(); - private static boolean useExtendedBoluses = false; +public class DanaRPlugin extends AbstractDanaRPlugin { private static DanaRPlugin plugin = null; @@ -77,9 +38,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C return plugin; } - public static PumpDescription pumpDescription = new PumpDescription(); - public DanaRPlugin() { + log = LoggerFactory.getLogger(DanaRPlugin.class); useExtendedBoluses = SP.getBoolean("danar_useextended", false); Context context = MainApp.instance().getApplicationContext(); @@ -147,83 +107,17 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C } // Plugin base interface - @Override - public int getType() { - return PluginBase.PUMP; - } - @Override public String getName() { return MainApp.instance().getString(R.string.danarpump); } - @Override - public String getNameShort() { - String name = MainApp.sResources.getString(R.string.danarpump_shortname); - if (!name.trim().isEmpty()) { - //only if translation exists - return name; - } - // use long name as fallback - return getName(); - } - - @Override - public boolean isEnabled(int type) { - if (type == PluginBase.PROFILE) return fragmentProfileEnabled && fragmentPumpEnabled; - else if (type == PluginBase.PUMP) return fragmentPumpEnabled; - else if (type == PluginBase.CONSTRAINTS) return fragmentPumpEnabled; - return false; - } - - @Override - public boolean isVisibleInTabs(int type) { - if (type == PluginBase.PROFILE || type == PluginBase.CONSTRAINTS) return false; - else if (type == PluginBase.PUMP) return fragmentPumpVisible; - return false; - } - - @Override - public boolean canBeHidden(int type) { - return true; - } - - @Override - public boolean hasFragment() { - return true; - } - - @Override - public boolean showInList(int type) { - return type == PUMP; - } - - @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { - if (type == PluginBase.PROFILE) - fragmentProfileEnabled = fragmentEnabled; - else if (type == PluginBase.PUMP) - fragmentPumpEnabled = fragmentEnabled; - // if pump profile was enabled need to switch to another too - if (type == PluginBase.PUMP && !fragmentEnabled && fragmentProfileEnabled) { - setFragmentEnabled(PluginBase.PROFILE, false); - setFragmentVisible(PluginBase.PROFILE, false); - NSProfilePlugin.getPlugin().setFragmentEnabled(PluginBase.PROFILE, true); - NSProfilePlugin.getPlugin().setFragmentVisible(PluginBase.PROFILE, true); - } - } - - @Override - public void setFragmentVisible(int type, boolean fragmentVisible) { - if (type == PluginBase.PUMP) - fragmentPumpVisible = fragmentVisible; - } - @Override public int getPreferencesId() { return R.xml.pref_danar; } + // Pump interface @Override public boolean isFakingTempsByExtendedBoluses() { return useExtendedBoluses; @@ -231,82 +125,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C @Override public boolean isInitialized() { - return pump.lastConnection.getTime() > 0 && pump.isExtendedBolusEnabled && pump.maxBasal > 0; - } - - @Override - public boolean isSuspended() { - return pump.pumpSuspended; - } - - @Override - public boolean isBusy() { - if (sExecutionService == null) return false; - return sExecutionService.isConnected() || sExecutionService.isConnecting(); - } - - // Pump interface - @Override - public PumpEnactResult setNewBasalProfile(Profile profile) { - PumpEnactResult result = new PumpEnactResult(); - - if (sExecutionService == null) { - log.error("setNewBasalProfile sExecutionService is null"); - result.comment = "setNewBasalProfile sExecutionService is null"; - return result; - } - if (!isInitialized()) { - log.error("setNewBasalProfile not initialized"); - Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notification)); - result.comment = MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet); - return result; - } else { - MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); - } - if (!sExecutionService.updateBasalsInPump(profile)) { - Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.sResources.getString(R.string.failedupdatebasalprofile), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notification)); - result.comment = MainApp.sResources.getString(R.string.failedupdatebasalprofile); - return result; - } else { - MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); - MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE)); - result.success = true; - result.enacted = true; - result.comment = "OK"; - return result; - } - } - - @Override - public boolean isThisProfileSet(Profile profile) { - if (!isInitialized()) - return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS - if (pump.pumpProfiles == null) - return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS - int basalValues = pump.basal48Enable ? 48 : 24; - int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60; - for (int h = 0; h < basalValues; h++) { - Double pumpValue = pump.pumpProfiles[pump.activeProfile][h]; - Double profileValue = profile.getBasal((Integer) (h * basalIncrement)); - if (profileValue == null) return true; - if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) { - log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); - return false; - } - } - return true; - } - - @Override - public Date lastDataTime() { - return pump.lastConnection; - } - - @Override - public double getBaseBasalRate() { - return pump.currentBasal; + return pump.lastConnection > 0 && pump.isExtendedBolusEnabled && pump.maxBasal > 0; } @Override @@ -316,7 +135,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { Treatment t = new Treatment(); boolean connectionOK = false; - if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, t); + if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t); PumpEnactResult result = new PumpEnactResult(); result.success = connectionOK; result.bolusDelivered = t.insulin; @@ -339,15 +158,6 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C } } - @Override - public void stopBolusDelivering() { - if (sExecutionService == null) { - log.error("stopBolusDelivering sExecutionService is null"); - return; - } - sExecutionService.bolusStop(); - } - // This is called from APS @Override public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) { @@ -500,100 +310,6 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C return result; } - @Override - public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) { - PumpEnactResult result = new PumpEnactResult(); - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - percent = configBuilderPlugin.applyBasalConstraints(percent); - if (percent < 0) { - result.isTempCancel = false; - result.enacted = false; - result.success = false; - result.comment = MainApp.instance().getString(R.string.danar_invalidinput); - log.error("setTempBasalPercent: Invalid input"); - return result; - } - if (percent > getPumpDescription().maxTempPercent) - percent = getPumpDescription().maxTempPercent; - TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); - if (runningTB != null && runningTB.percentRate == percent && !enforceNew) { - result.enacted = false; - result.success = true; - result.isTempCancel = false; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - result.duration = pump.tempBasalRemainingMin; - result.percent = pump.tempBasalPercent; - result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); - result.isPercent = true; - if (Config.logPumpActions) - log.debug("setTempBasalPercent: Correct value already set"); - return result; - } - int durationInHours = Math.max(durationInMinutes / 60, 1); - boolean connectionOK = sExecutionService.tempBasal(percent, durationInHours); - if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) { - result.enacted = true; - result.success = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - result.isTempCancel = false; - result.duration = pump.tempBasalRemainingMin; - result.percent = pump.tempBasalPercent; - result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); - result.isPercent = true; - if (Config.logPumpActions) - log.debug("setTempBasalPercent: OK"); - return result; - } - result.enacted = false; - result.success = false; - result.comment = MainApp.instance().getString(R.string.tempbasaldeliveryerror); - log.error("setTempBasalPercent: Failed to set temp basal"); - return result; - } - - @Override - public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - insulin = configBuilderPlugin.applyBolusConstraints(insulin); - // needs to be rounded - int durationInHalfHours = Math.max(durationInMinutes / 30, 1); - insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep); - - PumpEnactResult result = new PumpEnactResult(); - ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); - if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) { - result.enacted = false; - result.success = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - result.duration = pump.extendedBolusRemainingMinutes; - result.absolute = pump.extendedBolusAbsoluteRate; - result.isPercent = false; - result.isTempCancel = false; - if (Config.logPumpActions) - log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin); - return result; - } - boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours); - if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) { - result.enacted = true; - result.success = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - result.isTempCancel = false; - result.duration = pump.extendedBolusRemainingMinutes; - result.absolute = pump.extendedBolusAbsoluteRate; - result.bolusDelivered = pump.extendedBolusAmount; - result.isPercent = false; - if (Config.logPumpActions) - log.debug("setExtendedBolus: OK"); - return result; - } - result.enacted = false; - result.success = false; - result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly); - log.error("setExtendedBolus: Failed to extended bolus"); - return result; - } - @Override public PumpEnactResult cancelTempBasal(boolean force) { if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) @@ -634,257 +350,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C } } - @Override - public PumpEnactResult cancelExtendedBolus() { - PumpEnactResult result = new PumpEnactResult(); - ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); - if (runningEB != null) { - sExecutionService.extendedBolusStop(); - result.enacted = true; - result.isTempCancel = true; - } - if (!pump.isExtendedInProgress) { - result.success = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - if (Config.logPumpActions) - log.debug("cancelExtendedBolus: OK"); - return result; - } else { - result.success = false; - result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly); - log.error("cancelExtendedBolus: Failed to cancel extended bolus"); - return result; - } - } - - @Override - public void connect(String from) { - if (sExecutionService != null) { - sExecutionService.connect(from); - pumpDescription.basalStep = pump.basalStep; - pumpDescription.bolusStep = pump.bolusStep; - } - } - - @Override - public boolean isConnected() { - return sExecutionService != null && sExecutionService.isConnected(); - } - - @Override - public boolean isConnecting() { - return sExecutionService != null && sExecutionService.isConnecting(); - } - - @Override - public void disconnect(String from) { - if (sExecutionService != null) sExecutionService.disconnect(from); - } - - @Override - public void stopConnecting() { - if (sExecutionService != null) sExecutionService.stopConnecting(); - } - - @Override - public void getPumpStatus() { - if (sExecutionService != null) sExecutionService.getPumpStatus(); - } - - @Override - public JSONObject getJSONStatus() { - if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) { - return null; - } - JSONObject pumpjson = new JSONObject(); - JSONObject battery = new JSONObject(); - JSONObject status = new JSONObject(); - JSONObject extended = new JSONObject(); - try { - battery.put("percent", pump.batteryRemaining); - status.put("status", pump.pumpSuspended ? "suspended" : "normal"); - status.put("timestamp", DateUtil.toISOString(pump.lastConnection)); - extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION); - extended.put("PumpIOB", pump.iob); - if (pump.lastBolusTime.getTime() != 0) { - extended.put("LastBolus", pump.lastBolusTime.toLocaleString()); - extended.put("LastBolusAmount", pump.lastBolusAmount); - } - TemporaryBasal tb = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); - if (tb != null) { - extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis())); - extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date)); - extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes()); - } - ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); - if (eb != null) { - extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate()); - extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date)); - extended.put("ExtendedBolusRemaining", eb.getPlannedRemainingMinutes()); - } - extended.put("BaseBasalRate", getBaseBasalRate()); - try { - extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName()); - } catch (Exception e) { - } - - pumpjson.put("battery", battery); - pumpjson.put("status", status); - pumpjson.put("extended", extended); - pumpjson.put("reservoir", (int) pump.reservoirRemainingUnits); - pumpjson.put("clock", DateUtil.toISOString(new Date())); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return pumpjson; - } - - @Override - public String deviceID() { - return pump.serialNumber; - } - - @Override - public PumpDescription getPumpDescription() { - return pumpDescription; - } - - /** - * DanaR interface - */ - - @Override - public PumpEnactResult loadHistory(byte type) { - return sExecutionService.loadHistory(type); - } - @Override public PumpEnactResult loadEvents() { return null; // no history, not needed } - - /** - * Constraint interface - */ - - @Override - public boolean isLoopEnabled() { - return true; - } - - @Override - public boolean isClosedModeEnabled() { - return true; - } - - @Override - public boolean isAutosensModeEnabled() { - return true; - } - - @Override - public boolean isAMAModeEnabled() { - return true; - } - - @Override - public boolean isSMBModeEnabled() { - return true; - } - - @SuppressWarnings("PointlessBooleanExpression") - @Override - public Double applyBasalConstraints(Double absoluteRate) { - double origAbsoluteRate = absoluteRate; - if (pump != null) { - if (absoluteRate > pump.maxBasal) { - absoluteRate = pump.maxBasal; - if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit) - log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h"); - } - } - return absoluteRate; - } - - @SuppressWarnings("PointlessBooleanExpression") - @Override - public Integer applyBasalConstraints(Integer percentRate) { - Integer origPercentRate = percentRate; - if (percentRate < 0) percentRate = 0; - if (percentRate > getPumpDescription().maxTempPercent) - percentRate = getPumpDescription().maxTempPercent; - if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit)) - log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%"); - return percentRate; - } - - @SuppressWarnings("PointlessBooleanExpression") - @Override - public Double applyBolusConstraints(Double insulin) { - double origInsulin = insulin; - if (pump != null) { - if (insulin > pump.maxBolus) { - insulin = pump.maxBolus; - if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit) - log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U"); - } - } - return insulin; - } - - @Override - public Integer applyCarbsConstraints(Integer carbs) { - return carbs; - } - - @Override - public Double applyMaxIOBConstraints(Double maxIob) { - return maxIob; - } - - @Nullable - @Override - public ProfileStore getProfile() { - if (pump.lastSettingsRead.getTime() == 0) - return null; // no info now - return pump.createConvertedProfile(); - } - - @Override - public String getUnits() { - return pump.getUnits(); - } - - @Override - public String getProfileName() { - return pump.createConvertedProfileName(); - } - - // Reply for sms communicator - public String shortStatus(boolean veryShort) { - String ret = ""; - if (pump.lastConnection.getTime() != 0) { - Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime(); - int agoMin = (int) (agoMsec / 60d / 1000d); - ret += "LastConn: " + agoMin + " minago\n"; - } - if (pump.lastBolusTime.getTime() != 0) { - ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n"; - } - if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { - ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n"; - } - if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n"; - } - if (!veryShort) { - ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n"; - } - ret += "IOB: " + pump.iob + "U\n"; - ret += "Reserv: " + DecimalFormatter.to0Decimal(pump.reservoirRemainingUnits) + "U\n"; - ret += "Batt: " + pump.batteryRemaining + "\n"; - return ret; - } - // TODO: daily total constraint - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java index 9f88011c96..0e1a9ceb75 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java @@ -56,8 +56,8 @@ public class DanaRPump { public static final int CARBS = 14; public static final int PRIMECANNULA = 15; - public Date lastConnection = new Date(0); - public Date lastSettingsRead = new Date(0); + public long lastConnection = 0; + public long lastSettingsRead =0; // Info public String serialNumber = ""; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java index a333faecea..2f377a566a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java @@ -13,12 +13,13 @@ import java.io.OutputStream; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageHashTable; +import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractSerialIOThread; import info.nightscout.utils.CRC; /** * Created by mike on 17.07.2016. */ -public class SerialIOThread extends Thread { +public class SerialIOThread extends AbstractSerialIOThread { private static Logger log = LoggerFactory.getLogger(SerialIOThread.class); private InputStream mInputStream = null; @@ -28,10 +29,10 @@ public class SerialIOThread extends Thread { private boolean mKeepRunning = true; private byte[] mReadBuff = new byte[0]; - MessageBase processedMessage; + private MessageBase processedMessage; public SerialIOThread(BluetoothSocket rfcommSocket) { - super(SerialIOThread.class.toString()); + super(); mRfCommSocket = rfcommSocket; try { @@ -137,6 +138,7 @@ public class SerialIOThread extends Thread { } } + @Override public synchronized void sendMessage(MessageBase message) { if (!mRfCommSocket.isConnected()) { log.error("Socket not connected on sendMessage"); @@ -172,6 +174,7 @@ public class SerialIOThread extends Thread { } } + @Override public void disconnect(String reason) { mKeepRunning = false; try { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java index 17f90a1ba7..fe0d280113 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java @@ -35,8 +35,8 @@ public class MsgInitConnStatusTime extends MessageBase { MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginBase.PUMP, true); MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentEnabled(PluginBase.PUMP, false); MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentVisible(PluginBase.PUMP, false); - DanaRPump.getInstance().lastConnection = new Date(0); // mark not initialized + DanaRPump.getInstance().lastConnection = 0; // mark not initialized //If profile coming from pump, switch it as well if(MainApp.getSpecificPlugin(DanaRPlugin.class).isEnabled(PluginBase.PROFILE)){ (MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, false); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java index e1a7e45315..a47803c1b0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java @@ -23,7 +23,7 @@ public class MsgSettingBasal extends MessageBase { pump.pumpProfiles[pump.activeProfile] = new double[24]; for (int index = 0; index < 24; index++) { int basal = intFromBuff(bytes, 2 * index, 2); - if (basal < DanaRPlugin.pumpDescription.basalMinimumRate) basal = 0; + if (basal < DanaRPlugin.getPlugin().pumpDescription.basalMinimumRate) basal = 0; pump.pumpProfiles[pump.activeProfile][index] = basal / 100d; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java index 2d54d4f4a2..5d7b4b65ac 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java @@ -6,10 +6,12 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; +import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; /** * Created by mike on 13.12.2016. @@ -40,6 +42,11 @@ public class MsgSettingMeal extends MessageBase { log.debug("Is Config U/d: " + pump.isConfigUD); } + // DanaRKorean is not possible to set to 0.01 but it works when controlled from AAPS + if (DanaRKoreanPlugin.getPlugin().isEnabled(PluginBase.PUMP)) { + pump.basalStep = 0.01d; + } + if (pump.basalStep != 0.01d) { Notification notification = new Notification(Notification.WRONGBASALSTEP, MainApp.sResources.getString(R.string.danar_setbasalstep001), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java new file mode 100644 index 0000000000..d853c9abf1 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java @@ -0,0 +1,225 @@ +package info.nightscout.androidaps.plugins.PumpDanaR.services; + +import android.app.Service; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.IBinder; +import android.os.SystemClock; + +import org.slf4j.Logger; + +import java.io.IOException; +import java.util.Set; +import java.util.UUID; + +import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.db.Treatment; +import info.nightscout.androidaps.events.EventPumpStatusChanged; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; +import info.nightscout.androidaps.plugins.PumpDanaR.SerialIOThread; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStop; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryAlarm; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBasalHour; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBolus; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryCarbo; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDailyInsulin; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDone; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryError; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryGlucose; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryRefill; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistorySuspend; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStart; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStop; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; +import info.nightscout.utils.SP; +import info.nightscout.utils.ToastUtils; + +/** + * Created by mike on 28.01.2018. + */ + +public abstract class AbstractDanaRExecutionService extends Service { + protected Logger log; + + protected String mDevName; + + protected BluetoothSocket mRfcommSocket; + protected BluetoothDevice mBTDevice; + + protected DanaRPump mDanaRPump = DanaRPump.getInstance(); + protected Treatment mBolusingTreatment = null; + + protected Boolean mConnectionInProgress = false; + + protected AbstractSerialIOThread mSerialIOThread; + + protected IBinder mBinder; + + protected final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); + + public abstract boolean updateBasalsInPump(final Profile profile); + + public abstract void connect(); + + public abstract void getPumpStatus(); + + public abstract PumpEnactResult loadEvents(); + + public abstract boolean bolus(double amount, int carbs, long carbtime, final Treatment t); + + public abstract boolean highTempBasal(int percent); // Rv2 only + + public abstract boolean tempBasal(int percent, int durationInHours); + + public abstract boolean tempBasalStop(); + + public abstract boolean extendedBolus(double insulin, int durationInHalfHours); + + public abstract boolean extendedBolusStop(); + + + protected BroadcastReceiver receiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + String action = intent.getAction(); + if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { + log.debug("Device was disconnected " + device.getName());//Device was disconnected + if (mBTDevice != null && mBTDevice.getName() != null && mBTDevice.getName().equals(device.getName())) { + if (mSerialIOThread != null) { + mSerialIOThread.disconnect("BT disconnection broadcast"); + } + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED)); + } + } + } + }; + + @Override + public IBinder onBind(Intent intent) { + return mBinder; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return START_STICKY; + } + + public boolean isConnected() { + return mRfcommSocket != null && mRfcommSocket.isConnected(); + } + + public boolean isConnecting() { + return mConnectionInProgress; + } + + public void disconnect(String from) { + if (mSerialIOThread != null) + mSerialIOThread.disconnect(from); + } + + public void stopConnecting() { + if (mSerialIOThread != null) + mSerialIOThread.disconnect("stopConnecting"); + } + + protected void getBTSocketForSelectedPump() { + mDevName = SP.getString(MainApp.sResources.getString(R.string.key_danar_bt_name), ""); + BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + + if (bluetoothAdapter != null) { + Set bondedDevices = bluetoothAdapter.getBondedDevices(); + + for (BluetoothDevice device : bondedDevices) { + if (mDevName.equals(device.getName())) { + mBTDevice = device; + try { + mRfcommSocket = mBTDevice.createRfcommSocketToServiceRecord(SPP_UUID); + } catch (IOException e) { + log.error("Error creating socket: ", e); + } + break; + } + } + } else { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.nobtadapter)); + } + if (mBTDevice == null) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.devicenotfound)); + } + } + + public void bolusStop() { + if (Config.logDanaBTComm) + log.debug("bolusStop >>>>> @ " + (mBolusingTreatment == null ? "" : mBolusingTreatment.insulin)); + MsgBolusStop stop = new MsgBolusStop(); + stop.forced = true; + if (isConnected()) { + mSerialIOThread.sendMessage(stop); + while (!stop.stopped) { + mSerialIOThread.sendMessage(stop); + SystemClock.sleep(200); + } + } else { + stop.stopped = true; + } + } + + public PumpEnactResult loadHistory(byte type) { + PumpEnactResult result = new PumpEnactResult(); + if (!isConnected()) return result; + MessageBase msg = null; + switch (type) { + case RecordTypes.RECORD_TYPE_ALARM: + msg = new MsgHistoryAlarm(); + break; + case RecordTypes.RECORD_TYPE_BASALHOUR: + msg = new MsgHistoryBasalHour(); + break; + case RecordTypes.RECORD_TYPE_BOLUS: + msg = new MsgHistoryBolus(); + break; + case RecordTypes.RECORD_TYPE_CARBO: + msg = new MsgHistoryCarbo(); + break; + case RecordTypes.RECORD_TYPE_DAILY: + msg = new MsgHistoryDailyInsulin(); + break; + case RecordTypes.RECORD_TYPE_ERROR: + msg = new MsgHistoryError(); + break; + case RecordTypes.RECORD_TYPE_GLUCOSE: + msg = new MsgHistoryGlucose(); + break; + case RecordTypes.RECORD_TYPE_REFILL: + msg = new MsgHistoryRefill(); + break; + case RecordTypes.RECORD_TYPE_SUSPEND: + msg = new MsgHistorySuspend(); + break; + } + MsgHistoryDone done = new MsgHistoryDone(); + mSerialIOThread.sendMessage(new MsgPCCommStart()); + SystemClock.sleep(400); + mSerialIOThread.sendMessage(msg); + while (!done.received && mRfcommSocket.isConnected()) { + SystemClock.sleep(100); + } + SystemClock.sleep(200); + mSerialIOThread.sendMessage(new MsgPCCommStop()); + result.success = true; + result.comment = "OK"; + return result; + } + + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractSerialIOThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractSerialIOThread.java new file mode 100644 index 0000000000..1cca0b2512 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractSerialIOThread.java @@ -0,0 +1,13 @@ +package info.nightscout.androidaps.plugins.PumpDanaR.services; + +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; + +/** + * Created by mike on 28.01.2018. + */ + +public abstract class AbstractSerialIOThread extends Thread { + + public abstract void sendMessage(MessageBase message); + public abstract void disconnect(String reason); +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java index 0aa4b176c7..63215464a8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java @@ -1,41 +1,33 @@ package info.nightscout.androidaps.plugins.PumpDanaR.services; -import android.app.Service; -import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothSocket; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; import android.content.IntentFilter; import android.os.Binder; -import android.os.IBinder; import android.os.SystemClock; import com.squareup.otto.Subscribe; -import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Date; -import java.util.Set; -import java.util.UUID; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; -import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.SerialIOThread; @@ -45,18 +37,6 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStart; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStartWithSpeed; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStop; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgCheckValue; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryAlarm; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBasalHour; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBolus; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryCarbo; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDailyInsulin; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDone; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryError; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryGlucose; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryRefill; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistorySuspend; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStart; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStop; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetActivateBasalProfile; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetBasalProfile; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetCarbsEntry; @@ -67,9 +47,9 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStop; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTime; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingActiveProfile; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingBasal; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMeal; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingGlucose; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMaxValues; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMeal; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatios; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatiosAll; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingPumpTime; @@ -78,51 +58,18 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatus; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBasic; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBolusExtended; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusTempBasal; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; import info.nightscout.utils.ToastUtils; -public class DanaRExecutionService extends Service { - private static Logger log = LoggerFactory.getLogger(DanaRExecutionService.class); - - private String devName; - - private SerialIOThread mSerialIOThread; - private BluetoothSocket mRfcommSocket; - private BluetoothDevice mBTDevice; - - private IBinder mBinder = new LocalBinder(); - - private DanaRPump danaRPump = DanaRPump.getInstance(); - private Treatment bolusingTreatment = null; - - private static Boolean connectionInProgress = false; - - private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); - - private BroadcastReceiver receiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - String action = intent.getAction(); - if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { - log.debug("Device was disconnected " + device.getName());//Device was disconnected - if (mBTDevice != null && mBTDevice.getName() != null && mBTDevice.getName().equals(device.getName())) { - if (mSerialIOThread != null) { - mSerialIOThread.disconnect("BT disconnection broadcast"); - } - MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED)); - } - } - } - }; +public class DanaRExecutionService extends AbstractDanaRExecutionService{ public DanaRExecutionService() { + log = LoggerFactory.getLogger(DanaRExecutionService.class); + mBinder = new LocalBinder(); + registerBus(); MainApp.instance().getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED)); } @@ -133,17 +80,6 @@ public class DanaRExecutionService extends Service { } } - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - - return START_STICKY; - } - private void registerBus() { try { MainApp.bus().unregister(this); @@ -154,49 +90,27 @@ public class DanaRExecutionService extends Service { } @Subscribe - public void onStatusEvent(EventAppExit event) { - if (Config.logFunctionCalls) - log.debug("EventAppExit received"); - + public void onStatusEvent(final EventPreferenceChange pch) { if (mSerialIOThread != null) - mSerialIOThread.disconnect("Application exit"); - - MainApp.instance().getApplicationContext().unregisterReceiver(receiver); - - stopSelf(); - if (Config.logFunctionCalls) - log.debug("EventAppExit finished"); + mSerialIOThread.disconnect("EventPreferenceChange"); } - public boolean isConnected() { - return mRfcommSocket != null && mRfcommSocket.isConnected(); - } - - public boolean isConnecting() { - return connectionInProgress; - } - - public void disconnect(String from) { - if (mSerialIOThread != null) - mSerialIOThread.disconnect(from); - } - - public void connect(String from) { - if (danaRPump.password != -1 && danaRPump.password != SP.getInt(R.string.key_danar_password, -1)) { + public void connect() { + if (mDanaRPump.password != -1 && mDanaRPump.password != SP.getInt(R.string.key_danar_password, -1)) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.wrongpumppassword), R.raw.error); return; } - if (connectionInProgress) + if (mConnectionInProgress) return; new Thread(new Runnable() { @Override public void run() { - connectionInProgress = true; + mConnectionInProgress = true; getBTSocketForSelectedPump(); if (mRfcommSocket == null || mBTDevice == null) { - connectionInProgress = false; + mConnectionInProgress = false; return; // Device not found } @@ -217,48 +131,11 @@ public class DanaRExecutionService extends Service { MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTED, 0)); } - connectionInProgress = false; + mConnectionInProgress = false; } }).start(); } - public void stopConnecting() { - if (mSerialIOThread != null) - mSerialIOThread.disconnect("stopConnecting"); - } - - private void getBTSocketForSelectedPump() { - devName = SP.getString(MainApp.sResources.getString(R.string.key_danar_bt_name), ""); - BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - - if (bluetoothAdapter != null) { - Set bondedDevices = bluetoothAdapter.getBondedDevices(); - - for (BluetoothDevice device : bondedDevices) { - if (devName.equals(device.getName())) { - mBTDevice = device; - try { - mRfcommSocket = mBTDevice.createRfcommSocketToServiceRecord(SPP_UUID); - } catch (IOException e) { - log.error("Error creating socket: ", e); - } - break; - } - } - } else { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.nobtadapter)); - } - if (mBTDevice == null) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.devicenotfound)); - } - } - - @Subscribe - public void onStatusEvent(final EventPreferenceChange pch) { - if (mSerialIOThread != null) - mSerialIOThread.disconnect("EventPreferenceChange"); - } - public void getPumpStatus() { try { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpstatus))); @@ -268,7 +145,7 @@ public class DanaRExecutionService extends Service { MsgStatusBolusExtended exStatusMsg = new MsgStatusBolusExtended(); MsgCheckValue checkValue = new MsgCheckValue(); - if (danaRPump.isNewPump) { + if (mDanaRPump.isNewPump) { mSerialIOThread.sendMessage(checkValue); if (!checkValue.received) { return; @@ -283,8 +160,8 @@ public class DanaRExecutionService extends Service { mSerialIOThread.sendMessage(exStatusMsg); MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingbolusstatus))); - Date now = new Date(); - if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !MainApp.getSpecificPlugin(DanaRPlugin.class).isInitialized()) { + long now = System.currentTimeMillis(); + if (mDanaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRPlugin.class).isInitialized()) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpsettings))); mSerialIOThread.sendMessage(new MsgSettingShippingInfo()); mSerialIOThread.sendMessage(new MsgSettingActiveProfile()); @@ -298,26 +175,26 @@ public class DanaRExecutionService extends Service { mSerialIOThread.sendMessage(new MsgSettingProfileRatiosAll()); MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumptime))); mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - long timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; + long timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; log.debug("Pump time difference: " + timeDiff + " seconds"); if (Math.abs(timeDiff) > 10) { mSerialIOThread.sendMessage(new MsgSetTime(new Date())); mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; + timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; log.debug("Pump time difference: " + timeDiff + " seconds"); } - danaRPump.lastSettingsRead = now; + mDanaRPump.lastSettingsRead = now; } - danaRPump.lastConnection = now; + mDanaRPump.lastConnection = now; MainApp.bus().post(new EventDanaRNewStatus()); MainApp.bus().post(new EventInitializationChanged()); NSUpload.uploadDeviceStatus(); - if (danaRPump.dailyTotalUnits > danaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { - log.debug("Approaching daily limit: " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits); + if (mDanaRPump.dailyTotalUnits > mDanaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { + log.debug("Approaching daily limit: " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits); Notification reportFail = new Notification(Notification.APPROACHING_DAILY_LIMIT, MainApp.sResources.getString(R.string.approachingdailylimit), Notification.URGENT); MainApp.bus().post(new EventNewNotification(reportFail)); - NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits + "U"); + NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits + "U"); } } catch (Exception e) { log.error("Unhandled exception", e); @@ -326,10 +203,10 @@ public class DanaRExecutionService extends Service { public boolean tempBasal(int percent, int durationInHours) { if (!isConnected()) return false; - if (danaRPump.isTempBasalInProgress) { + if (mDanaRPump.isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); - waitMsec(500); + SystemClock.sleep(500); } MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.settingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStart(percent, durationInHours)); @@ -365,11 +242,16 @@ public class DanaRExecutionService extends Service { return true; } - public boolean bolus(double amount, int carbs, final Treatment t) { + @Override + public PumpEnactResult loadEvents() { + return null; + } + + public boolean bolus(double amount, int carbs, long carbtime, final Treatment t) { if (!isConnected()) return false; if (BolusProgressDialog.stopPressed) return false; - bolusingTreatment = t; + mBolusingTreatment = t; int preferencesSpeed = SP.getInt(R.string.key_danars_bolusspeed, 0); MessageBase start; if (preferencesSpeed == 0) @@ -379,7 +261,7 @@ public class DanaRExecutionService extends Service { MsgBolusStop stop = new MsgBolusStop(amount, t); if (carbs > 0) { - mSerialIOThread.sendMessage(new MsgSetCarbsEntry(System.currentTimeMillis(), carbs)); + mSerialIOThread.sendMessage(new MsgSetCarbsEntry(carbtime, carbs)); } MsgBolusProgress progress = new MsgBolusProgress(amount, t); // initialize static variables @@ -392,20 +274,20 @@ public class DanaRExecutionService extends Service { return false; } while (!stop.stopped && !start.failed) { - waitMsec(100); + SystemClock.sleep(100); if ((System.currentTimeMillis() - progress.lastReceive) > 15 * 1000L) { // if i didn't receive status for more than 15 sec expecting broken comm stop.stopped = true; stop.forced = true; log.debug("Communication stopped"); } } - waitMsec(300); + SystemClock.sleep(300); EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance(); bolusingEvent.t = t; bolusingEvent.percent = 99; - bolusingTreatment = null; + mBolusingTreatment = null; int speed = 12; switch (preferencesSpeed) { @@ -437,11 +319,11 @@ public class DanaRExecutionService extends Service { ConfigBuilderPlugin.getCommandQueue().independentConnect("bolusingInterrupted", new Callback() { @Override public void run() { - if (danaRPump.lastBolusTime.getTime() > System.currentTimeMillis() - 60 * 1000L) { // last bolus max 1 min old - t.insulin = danaRPump.lastBolusAmount; - log.debug("Used bolus amount from history: " + danaRPump.lastBolusAmount); + if (mDanaRPump.lastBolusTime.getTime() > System.currentTimeMillis() - 60 * 1000L) { // last bolus max 1 min old + t.insulin = mDanaRPump.lastBolusAmount; + log.debug("Used bolus amount from history: " + mDanaRPump.lastBolusAmount); } else { - log.debug("Bolus amount in history too old: " + danaRPump.lastBolusTime.toLocaleString()); + log.debug("Bolus amount in history too old: " + mDanaRPump.lastBolusTime.toLocaleString()); } synchronized (o) { o.notify(); @@ -460,22 +342,6 @@ public class DanaRExecutionService extends Service { return true; } - public void bolusStop() { - if (Config.logDanaBTComm) - log.debug("bolusStop >>>>> @ " + (bolusingTreatment == null ? "" : bolusingTreatment.insulin)); - MsgBolusStop stop = new MsgBolusStop(); - stop.forced = true; - if (isConnected()) { - mSerialIOThread.sendMessage(stop); - while (!stop.stopped) { - mSerialIOThread.sendMessage(stop); - waitMsec(200); - } - } else { - stop.stopped = true; - } - } - public boolean carbsEntry(int amount) { if (!isConnected()) return false; MsgSetCarbsEntry msg = new MsgSetCarbsEntry(System.currentTimeMillis(), amount); @@ -483,51 +349,9 @@ public class DanaRExecutionService extends Service { return true; } - public PumpEnactResult loadHistory(byte type) { - PumpEnactResult result = new PumpEnactResult(); - if (!isConnected()) return result; - MessageBase msg = null; - switch (type) { - case RecordTypes.RECORD_TYPE_ALARM: - msg = new MsgHistoryAlarm(); - break; - case RecordTypes.RECORD_TYPE_BASALHOUR: - msg = new MsgHistoryBasalHour(); - break; - case RecordTypes.RECORD_TYPE_BOLUS: - msg = new MsgHistoryBolus(); - break; - case RecordTypes.RECORD_TYPE_CARBO: - msg = new MsgHistoryCarbo(); - break; - case RecordTypes.RECORD_TYPE_DAILY: - msg = new MsgHistoryDailyInsulin(); - break; - case RecordTypes.RECORD_TYPE_ERROR: - msg = new MsgHistoryError(); - break; - case RecordTypes.RECORD_TYPE_GLUCOSE: - msg = new MsgHistoryGlucose(); - break; - case RecordTypes.RECORD_TYPE_REFILL: - msg = new MsgHistoryRefill(); - break; - case RecordTypes.RECORD_TYPE_SUSPEND: - msg = new MsgHistorySuspend(); - break; - } - MsgHistoryDone done = new MsgHistoryDone(); - mSerialIOThread.sendMessage(new MsgPCCommStart()); - waitMsec(400); - mSerialIOThread.sendMessage(msg); - while (!done.received && mRfcommSocket.isConnected()) { - waitMsec(100); - } - waitMsec(200); - mSerialIOThread.sendMessage(new MsgPCCommStop()); - result.success = true; - result.comment = "OK"; - return result; + @Override + public boolean highTempBasal(int percent) { + return false; } public boolean updateBasalsInPump(final Profile profile) { @@ -538,13 +362,25 @@ public class DanaRExecutionService extends Service { mSerialIOThread.sendMessage(msgSet); MsgSetActivateBasalProfile msgActivate = new MsgSetActivateBasalProfile((byte) 0); mSerialIOThread.sendMessage(msgActivate); - danaRPump.lastSettingsRead = new Date(0); // force read full settings + mDanaRPump.lastSettingsRead = 0; // force read full settings getPumpStatus(); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); return true; } - private void waitMsec(long msecs) { - SystemClock.sleep(msecs); + @Subscribe + public void onStatusEvent(EventAppExit event) { + if (Config.logFunctionCalls) + log.debug("EventAppExit received"); + + if (mSerialIOThread != null) + mSerialIOThread.disconnect("Application exit"); + + MainApp.instance().getApplicationContext().unregisterReceiver(receiver); + + stopSelf(); + if (Config.logFunctionCalls) + log.debug("EventAppExit finished"); } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java index e92febada6..58392e65f9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java @@ -5,71 +5,31 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; -import android.support.annotation.Nullable; import com.squareup.otto.Subscribe; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; -import java.util.Objects; - -import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventPreferenceChange; -import info.nightscout.androidaps.interfaces.ConstraintsInterface; -import info.nightscout.androidaps.interfaces.DanaRInterface; -import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpDescription; -import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; -import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; -import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; -import info.nightscout.androidaps.plugins.PumpDanaR.DanaRFragment; -import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; +import info.nightscout.androidaps.plugins.PumpDanaR.AbstractDanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaRKorean.services.DanaRKoreanExecutionService; -import info.nightscout.utils.DateUtil; -import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.Round; import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. */ -public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface { - private static Logger log = LoggerFactory.getLogger(DanaRKoreanPlugin.class); - - @Override - public String getFragmentClass() { - return DanaRFragment.class.getName(); - } - - private static boolean fragmentPumpEnabled = false; - private static boolean fragmentProfileEnabled = false; - private static boolean fragmentPumpVisible = true; - - private static DanaRKoreanExecutionService sExecutionService; - - - private static DanaRPump pump = DanaRPump.getInstance(); - private boolean useExtendedBoluses = false; +public class DanaRKoreanPlugin extends AbstractDanaRPlugin { private static DanaRKoreanPlugin plugin = null; @@ -79,9 +39,8 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf return plugin; } - public static PumpDescription pumpDescription = new PumpDescription(); - public DanaRKoreanPlugin() { + log = LoggerFactory.getLogger(DanaRKoreanPlugin.class); useExtendedBoluses = SP.getBoolean("danar_useextended", false); Context context = MainApp.instance().getApplicationContext(); @@ -149,83 +108,17 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf } // Plugin base interface - @Override - public int getType() { - return PluginBase.PUMP; - } - @Override public String getName() { return MainApp.instance().getString(R.string.danarkoreanpump); } - @Override - public String getNameShort() { - String name = MainApp.sResources.getString(R.string.danarpump_shortname); - if (!name.trim().isEmpty()) { - //only if translation exists - return name; - } - // use long name as fallback - return getName(); - } - - @Override - public boolean isEnabled(int type) { - if (type == PluginBase.PROFILE) return fragmentProfileEnabled && fragmentPumpEnabled; - else if (type == PluginBase.PUMP) return fragmentPumpEnabled; - else if (type == PluginBase.CONSTRAINTS) return fragmentPumpEnabled; - return false; - } - - @Override - public boolean isVisibleInTabs(int type) { - if (type == PluginBase.PROFILE || type == PluginBase.CONSTRAINTS) return false; - else if (type == PluginBase.PUMP) return fragmentPumpVisible; - return false; - } - - @Override - public boolean canBeHidden(int type) { - return true; - } - - @Override - public boolean hasFragment() { - return true; - } - - @Override - public boolean showInList(int type) { - return type == PUMP; - } - - @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { - if (type == PluginBase.PROFILE) - fragmentProfileEnabled = fragmentEnabled; - else if (type == PluginBase.PUMP) - fragmentPumpEnabled = fragmentEnabled; - // if pump profile was enabled need to switch to another too - if (type == PluginBase.PUMP && !fragmentEnabled && fragmentProfileEnabled) { - setFragmentEnabled(PluginBase.PROFILE, false); - setFragmentVisible(PluginBase.PROFILE, false); - NSProfilePlugin.getPlugin().setFragmentEnabled(PluginBase.PROFILE, true); - NSProfilePlugin.getPlugin().setFragmentVisible(PluginBase.PROFILE, true); - } - } - - @Override - public void setFragmentVisible(int type, boolean fragmentVisible) { - if (type == PluginBase.PUMP) - fragmentPumpVisible = fragmentVisible; - } - @Override public int getPreferencesId() { return R.xml.pref_danarkorean; } + // Pump interface @Override public boolean isFakingTempsByExtendedBoluses() { return useExtendedBoluses; @@ -233,82 +126,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf @Override public boolean isInitialized() { - return pump.lastConnection.getTime() > 0 && pump.maxBasal > 0 && !pump.isConfigUD && !pump.isEasyModeEnabled && pump.isExtendedBolusEnabled; - } - - @Override - public boolean isSuspended() { - return pump.pumpSuspended; - } - - @Override - public boolean isBusy() { - if (sExecutionService == null) return false; - return sExecutionService.isConnected() || sExecutionService.isConnecting(); - } - - // Pump interface - @Override - public PumpEnactResult setNewBasalProfile(Profile profile) { - PumpEnactResult result = new PumpEnactResult(); - - if (sExecutionService == null) { - log.error("setNewBasalProfile sExecutionService is null"); - result.comment = "setNewBasalProfile sExecutionService is null"; - return result; - } - if (!isInitialized()) { - log.error("setNewBasalProfile not initialized"); - Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notification)); - result.comment = MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet); - return result; - } else { - MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); - } - if (!sExecutionService.updateBasalsInPump(profile)) { - Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.sResources.getString(R.string.failedupdatebasalprofile), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notification)); - result.comment = MainApp.sResources.getString(R.string.failedupdatebasalprofile); - return result; - } else { - MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); - MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE)); - result.success = true; - result.enacted = true; - result.comment = "OK"; - return result; - } - } - - @Override - public boolean isThisProfileSet(Profile profile) { - if (!isInitialized()) - return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS - if (pump.pumpProfiles == null) - return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS - int basalValues = pump.basal48Enable ? 48 : 24; - int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60; - for (int h = 0; h < basalValues; h++) { - Double pumpValue = pump.pumpProfiles[pump.activeProfile][h]; - Double profileValue = profile.getBasal((Integer) (h * basalIncrement)); - if (profileValue == null) return true; - if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) { - log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); - return false; - } - } - return true; - } - - @Override - public Date lastDataTime() { - return pump.lastConnection; - } - - @Override - public double getBaseBasalRate() { - return pump.currentBasal; + return pump.lastConnection > 0 && pump.maxBasal > 0 && !pump.isConfigUD && !pump.isEasyModeEnabled && pump.isExtendedBolusEnabled; } @Override @@ -318,7 +136,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { Treatment t = new Treatment(); boolean connectionOK = false; - if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, t); + if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t); PumpEnactResult result = new PumpEnactResult(); result.success = connectionOK; result.bolusDelivered = t.insulin; @@ -341,15 +159,6 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf } } - @Override - public void stopBolusDelivering() { - if (sExecutionService == null) { - log.error("stopBolusDelivering sExecutionService is null"); - return; - } - sExecutionService.bolusStop(); - } - // This is called from APS @Override public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) { @@ -502,100 +311,6 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf return result; } - @Override - public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) { - PumpEnactResult result = new PumpEnactResult(); - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - percent = configBuilderPlugin.applyBasalConstraints(percent); - if (percent < 0) { - result.isTempCancel = false; - result.enacted = false; - result.success = false; - result.comment = MainApp.instance().getString(R.string.danar_invalidinput); - log.error("setTempBasalPercent: Invalid input"); - return result; - } - if (percent > getPumpDescription().maxTempPercent) - percent = getPumpDescription().maxTempPercent; - TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); - if (runningTB != null && runningTB.percentRate == percent && enforceNew) { - result.enacted = false; - result.success = true; - result.isTempCancel = false; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - result.duration = pump.tempBasalRemainingMin; - result.percent = pump.tempBasalPercent; - result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); - result.isPercent = true; - if (Config.logPumpActions) - log.debug("setTempBasalPercent: Correct value already set"); - return result; - } - int durationInHours = Math.max(durationInMinutes / 60, 1); - boolean connectionOK = sExecutionService.tempBasal(percent, durationInHours); - if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) { - result.enacted = true; - result.success = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - result.isTempCancel = false; - result.duration = pump.tempBasalRemainingMin; - result.percent = pump.tempBasalPercent; - result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); - result.isPercent = true; - if (Config.logPumpActions) - log.debug("setTempBasalPercent: OK"); - return result; - } - result.enacted = false; - result.success = false; - result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly); - log.error("setTempBasalPercent: Failed to set temp basal"); - return result; - } - - @Override - public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - insulin = configBuilderPlugin.applyBolusConstraints(insulin); - // needs to be rounded - int durationInHalfHours = Math.max(durationInMinutes / 30, 1); - insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep); - - PumpEnactResult result = new PumpEnactResult(); - ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); - if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) { - result.enacted = false; - result.success = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - result.duration = pump.extendedBolusRemainingMinutes; - result.absolute = pump.extendedBolusAbsoluteRate; - result.isPercent = false; - result.isTempCancel = false; - if (Config.logPumpActions) - log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin); - return result; - } - boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours); - if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) { - result.enacted = true; - result.success = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - result.isTempCancel = false; - result.duration = pump.extendedBolusRemainingMinutes; - result.absolute = pump.extendedBolusAbsoluteRate; - result.bolusDelivered = pump.extendedBolusAmount; - result.isPercent = false; - if (Config.logPumpActions) - log.debug("setExtendedBolus: OK"); - return result; - } - result.enacted = false; - result.success = false; - result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly); - log.error("setExtendedBolus: Failed to extended bolus"); - return result; - } - @Override public PumpEnactResult cancelTempBasal(boolean force) { if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) @@ -636,257 +351,8 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf } } - @Override - public PumpEnactResult cancelExtendedBolus() { - PumpEnactResult result = new PumpEnactResult(); - ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); - if (runningEB != null) { - sExecutionService.extendedBolusStop(); - result.enacted = true; - result.isTempCancel = true; - } - if (!pump.isExtendedInProgress) { - result.success = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - if (Config.logPumpActions) - log.debug("cancelExtendedBolus: OK"); - return result; - } else { - result.success = false; - result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly); - log.error("cancelExtendedBolus: Failed to cancel extended bolus"); - return result; - } - } - - @Override - public void connect(String from) { - if (sExecutionService != null) { - sExecutionService.connect(from); - pumpDescription.basalStep = pump.basalStep; - pumpDescription.bolusStep = pump.bolusStep; - } - } - - @Override - public boolean isConnected() { - return sExecutionService != null && sExecutionService.isConnected(); - } - - @Override - public boolean isConnecting() { - return sExecutionService != null && sExecutionService.isConnecting(); - } - - @Override - public void disconnect(String from) { - if (sExecutionService != null) sExecutionService.disconnect(from); - } - - @Override - public void stopConnecting() { - if (sExecutionService != null) sExecutionService.stopConnecting(); - } - - @Override - public void getPumpStatus() { - if (sExecutionService != null) sExecutionService.getPumpStatus(); - } - - @Override - public JSONObject getJSONStatus() { - if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) { - return null; - } - JSONObject pumpjson = new JSONObject(); - JSONObject battery = new JSONObject(); - JSONObject status = new JSONObject(); - JSONObject extended = new JSONObject(); - try { - battery.put("percent", pump.batteryRemaining); - status.put("status", pump.pumpSuspended ? "suspended" : "normal"); - status.put("timestamp", DateUtil.toISOString(pump.lastConnection)); - extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION); - extended.put("PumpIOB", pump.iob); - if (pump.lastBolusTime.getTime() != 0) { - extended.put("LastBolus", pump.lastBolusTime.toLocaleString()); - extended.put("LastBolusAmount", pump.lastBolusAmount); - } - TemporaryBasal tb = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); - if (tb != null) { - extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis())); - extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date)); - extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes()); - } - ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); - if (eb != null) { - extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate()); - extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date)); - extended.put("ExtendedBolusRemaining", eb.getPlannedRemainingMinutes()); - } - extended.put("BaseBasalRate", getBaseBasalRate()); - try { - extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName()); - } catch (Exception e) { - } - - pumpjson.put("battery", battery); - pumpjson.put("status", status); - pumpjson.put("extended", extended); - pumpjson.put("reservoir", (int) pump.reservoirRemainingUnits); - pumpjson.put("clock", DateUtil.toISOString(new Date())); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return pumpjson; - } - - @Override - public String deviceID() { - return pump.serialNumber; - } - - @Override - public PumpDescription getPumpDescription() { - return pumpDescription; - } - - /** - * DanaR interface - */ - - @Override - public PumpEnactResult loadHistory(byte type) { - return sExecutionService.loadHistory(type); - } - @Override public PumpEnactResult loadEvents() { return null; // no history, not needed } - - /** - * Constraint interface - */ - - @Override - public boolean isLoopEnabled() { - return true; - } - - @Override - public boolean isClosedModeEnabled() { - return true; - } - - @Override - public boolean isAutosensModeEnabled() { - return true; - } - - @Override - public boolean isAMAModeEnabled() { - return true; - } - - @Override - public boolean isSMBModeEnabled() { - return true; - } - - @SuppressWarnings("PointlessBooleanExpression") - @Override - public Double applyBasalConstraints(Double absoluteRate) { - double origAbsoluteRate = absoluteRate; - if (pump != null) { - if (absoluteRate > pump.maxBasal) { - absoluteRate = pump.maxBasal; - if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit) - log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h"); - } - } - return absoluteRate; - } - - @SuppressWarnings("PointlessBooleanExpression") - @Override - public Integer applyBasalConstraints(Integer percentRate) { - Integer origPercentRate = percentRate; - if (percentRate < 0) percentRate = 0; - if (percentRate > getPumpDescription().maxTempPercent) - percentRate = getPumpDescription().maxTempPercent; - if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit)) - log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%"); - return percentRate; - } - - @SuppressWarnings("PointlessBooleanExpression") - @Override - public Double applyBolusConstraints(Double insulin) { - double origInsulin = insulin; - if (pump != null) { - if (insulin > pump.maxBolus) { - insulin = pump.maxBolus; - if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit) - log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U"); - } - } - return insulin; - } - - @Override - public Integer applyCarbsConstraints(Integer carbs) { - return carbs; - } - - @Override - public Double applyMaxIOBConstraints(Double maxIob) { - return maxIob; - } - - @Nullable - @Override - public ProfileStore getProfile() { - if (pump.lastSettingsRead.getTime() == 0) - return null; // no info now - return pump.createConvertedProfile(); - } - - @Override - public String getUnits() { - return pump.getUnits(); - } - - @Override - public String getProfileName() { - return pump.createConvertedProfileName(); - } - - // Reply for sms communicator - public String shortStatus(boolean veryShort) { - String ret = ""; - if (pump.lastConnection.getTime() != 0) { - Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime(); - int agoMin = (int) (agoMsec / 60d / 1000d); - ret += "LastConn: " + agoMin + " minago\n"; - } - if (pump.lastBolusTime.getTime() != 0) { - ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n"; - } - if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { - ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n"; - } - if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n"; - } - if (!veryShort) { - ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n"; - } - ret += "IOB: " + pump.iob + "U\n"; - ret += "Reserv: " + DecimalFormatter.to0Decimal(pump.reservoirRemainingUnits) + "U\n"; - ret += "Batt: " + pump.batteryRemaining + "\n"; - return ret; - } - // TODO: daily total constraint - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java index 8672afdcb0..9a8f3edb05 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java @@ -13,13 +13,14 @@ import java.io.OutputStream; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; +import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractSerialIOThread; import info.nightscout.androidaps.plugins.PumpDanaRKorean.comm.MessageHashTable_k; import info.nightscout.utils.CRC; /** * Created by mike on 17.07.2016. */ -public class SerialIOThread extends Thread { +public class SerialIOThread extends AbstractSerialIOThread { private static Logger log = LoggerFactory.getLogger(SerialIOThread.class); private InputStream mInputStream = null; @@ -29,10 +30,10 @@ public class SerialIOThread extends Thread { private boolean mKeepRunning = true; private byte[] mReadBuff = new byte[0]; - MessageBase processedMessage; + private MessageBase processedMessage; public SerialIOThread(BluetoothSocket rfcommSocket) { - super(SerialIOThread.class.toString()); + super(); mRfCommSocket = rfcommSocket; try { @@ -138,6 +139,7 @@ public class SerialIOThread extends Thread { } } + @Override public synchronized void sendMessage(MessageBase message) { if (!mRfCommSocket.isConnected()) { log.error("Socket not connected on sendMessage"); @@ -173,6 +175,7 @@ public class SerialIOThread extends Thread { } } + @Override public void disconnect(String reason) { mKeepRunning = false; try { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java index 641dce79f3..3cf47b656f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java @@ -37,7 +37,7 @@ public class MsgInitConnStatusTime_k extends MessageBase { MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginBase.PUMP, false); MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentEnabled(PluginBase.PUMP, true); MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentVisible(PluginBase.PUMP, true); - DanaRPump.getInstance().lastConnection = new Date(0); // mark not initialized + DanaRPump.getInstance().lastConnection = 0; // mark not initialized //If profile coming from pump, switch it as well if (MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isEnabled(PluginBase.PROFILE)) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java index 72a8be4e42..5c8b40b959 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java @@ -24,7 +24,7 @@ public class MsgSettingBasal_k extends MessageBase { pump.pumpProfiles[pump.activeProfile] = new double[24]; for (int index = 0; index < 24; index++) { int basal = intFromBuff(bytes, 2 * index, 2); - if (basal < DanaRKoreanPlugin.pumpDescription.basalMinimumRate) basal = 0; + if (basal < DanaRKoreanPlugin.getPlugin().pumpDescription.basalMinimumRate) basal = 0; pump.pumpProfiles[pump.activeProfile][index] = basal / 100d; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java index 4efff4a5ad..6d1ccc132d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java @@ -1,58 +1,36 @@ package info.nightscout.androidaps.plugins.PumpDanaRKorean.services; -import android.app.Service; -import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothSocket; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; import android.content.IntentFilter; import android.os.Binder; -import android.os.IBinder; import android.os.SystemClock; import com.squareup.otto.Subscribe; -import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Date; -import java.util.Set; -import java.util.UUID; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; -import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; -import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusProgress; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStart; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStop; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryAlarm; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBasalHour; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBolus; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryCarbo; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDailyInsulin; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDone; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryError; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryGlucose; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryRefill; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistorySuspend; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStart; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStop; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetCarbsEntry; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetExtendedBolusStart; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetExtendedBolusStop; @@ -68,56 +46,23 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingPumpTime; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingShippingInfo; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBolusExtended; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusTempBasal; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; +import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractDanaRExecutionService; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.PumpDanaRKorean.SerialIOThread; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.PumpDanaRKorean.comm.MsgCheckValue_k; import info.nightscout.androidaps.plugins.PumpDanaRKorean.comm.MsgSettingBasal_k; import info.nightscout.androidaps.plugins.PumpDanaRKorean.comm.MsgStatusBasic_k; -import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; import info.nightscout.utils.ToastUtils; -public class DanaRKoreanExecutionService extends Service { - private static Logger log = LoggerFactory.getLogger(DanaRKoreanExecutionService.class); - - private String devName; - - private SerialIOThread mSerialIOThread; - private BluetoothSocket mRfcommSocket; - private BluetoothDevice mBTDevice; - - private IBinder mBinder = new LocalBinder(); - - private DanaRPump danaRPump = DanaRPump.getInstance(); - private Treatment bolusingTreatment = null; - - private static Boolean connectionInProgress = false; - - private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); - - private BroadcastReceiver receiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - String action = intent.getAction(); - if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { - log.debug("Device was disconnected " + device.getName());//Device was disconnected - if (mBTDevice != null && mBTDevice.getName() != null && mBTDevice.getName().equals(device.getName())) { - if (mSerialIOThread != null) { - mSerialIOThread.disconnect("BT disconnection broadcast"); - } - MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED)); - } - } - } - }; +public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { public DanaRKoreanExecutionService() { + log = LoggerFactory.getLogger(DanaRKoreanExecutionService.class); + mBinder = new LocalBinder(); + registerBus(); MainApp.instance().getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED)); } @@ -128,17 +73,6 @@ public class DanaRKoreanExecutionService extends Service { } } - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - - return START_STICKY; - } - private void registerBus() { try { MainApp.bus().unregister(this); @@ -163,35 +97,28 @@ public class DanaRKoreanExecutionService extends Service { log.debug("EventAppExit finished"); } - public boolean isConnected() { - return mRfcommSocket != null && mRfcommSocket.isConnected(); - } - - public boolean isConnecting() { - return connectionInProgress; - } - - public void disconnect(String from) { + @Subscribe + public void onStatusEvent(final EventPreferenceChange pch) { if (mSerialIOThread != null) - mSerialIOThread.disconnect(from); + mSerialIOThread.disconnect("EventPreferenceChange"); } - public void connect(String from) { - if (danaRPump.password != -1 && danaRPump.password != SP.getInt(R.string.key_danar_password, -1)) { + public void connect() { + if (mDanaRPump.password != -1 && mDanaRPump.password != SP.getInt(R.string.key_danar_password, -1)) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.wrongpumppassword), R.raw.error); return; } - if (connectionInProgress) + if (mConnectionInProgress) return; new Thread(new Runnable() { @Override public void run() { - connectionInProgress = true; + mConnectionInProgress = true; getBTSocketForSelectedPump(); if (mRfcommSocket == null || mBTDevice == null) { - connectionInProgress = false; + mConnectionInProgress = false; return; // Device not found } @@ -212,48 +139,11 @@ public class DanaRKoreanExecutionService extends Service { MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTED, 0)); } - connectionInProgress = false; + mConnectionInProgress = false; } }).start(); } - public void stopConnecting() { - if (mSerialIOThread != null) - mSerialIOThread.disconnect("stopConnecting"); - } - - private void getBTSocketForSelectedPump() { - devName = SP.getString(MainApp.sResources.getString(R.string.key_danar_bt_name), ""); - BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - - if (bluetoothAdapter != null) { - Set bondedDevices = bluetoothAdapter.getBondedDevices(); - - for (BluetoothDevice device : bondedDevices) { - if (devName.equals(device.getName())) { - mBTDevice = device; - try { - mRfcommSocket = mBTDevice.createRfcommSocketToServiceRecord(SPP_UUID); - } catch (IOException e) { - log.error("Error creating socket: ", e); - } - break; - } - } - } else { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.nobtadapter)); - } - if (mBTDevice == null) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.devicenotfound)); - } - } - - @Subscribe - public void onStatusEvent(final EventPreferenceChange pch) { - if (mSerialIOThread != null) - mSerialIOThread.disconnect("EventPreferenceChange"); - } - public void getPumpStatus() { try { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpstatus))); @@ -263,7 +153,7 @@ public class DanaRKoreanExecutionService extends Service { MsgStatusBolusExtended exStatusMsg = new MsgStatusBolusExtended(); MsgCheckValue_k checkValue = new MsgCheckValue_k(); - if (danaRPump.isNewPump) { + if (mDanaRPump.isNewPump) { mSerialIOThread.sendMessage(checkValue); if (!checkValue.received) { return; @@ -278,8 +168,8 @@ public class DanaRKoreanExecutionService extends Service { mSerialIOThread.sendMessage(exStatusMsg); MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingbolusstatus))); - Date now = new Date(); - if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isInitialized()) { + long now = System.currentTimeMillis(); + if (mDanaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isInitialized()) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpsettings))); mSerialIOThread.sendMessage(new MsgSettingShippingInfo()); mSerialIOThread.sendMessage(new MsgSettingMeal()); @@ -290,39 +180,38 @@ public class DanaRKoreanExecutionService extends Service { mSerialIOThread.sendMessage(new MsgSettingProfileRatios()); MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumptime))); mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - long timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; + long timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; log.debug("Pump time difference: " + timeDiff + " seconds"); if (Math.abs(timeDiff) > 10) { mSerialIOThread.sendMessage(new MsgSetTime(new Date())); mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; + timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; log.debug("Pump time difference: " + timeDiff + " seconds"); } - danaRPump.lastSettingsRead = now; + mDanaRPump.lastSettingsRead = now; } - danaRPump.lastConnection = now; + mDanaRPump.lastConnection = now; MainApp.bus().post(new EventDanaRNewStatus()); MainApp.bus().post(new EventInitializationChanged()); NSUpload.uploadDeviceStatus(); - if (danaRPump.dailyTotalUnits > danaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { - log.debug("Approaching daily limit: " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits); + if (mDanaRPump.dailyTotalUnits > mDanaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { + log.debug("Approaching daily limit: " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits); Notification reportFail = new Notification(Notification.APPROACHING_DAILY_LIMIT, MainApp.sResources.getString(R.string.approachingdailylimit), Notification.URGENT); MainApp.bus().post(new EventNewNotification(reportFail)); - NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits + "U"); + NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits + "U"); } } catch (Exception e) { log.error("Unhandled exception", e); } - return; } public boolean tempBasal(int percent, int durationInHours) { if (!isConnected()) return false; - if (danaRPump.isTempBasalInProgress) { + if (mDanaRPump.isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); - waitMsec(500); + SystemClock.sleep(500); } MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.settingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStart(percent, durationInHours)); @@ -358,16 +247,21 @@ public class DanaRKoreanExecutionService extends Service { return true; } - public boolean bolus(double amount, int carbs, final Treatment t) { + @Override + public PumpEnactResult loadEvents() { + return null; + } + + public boolean bolus(double amount, int carbs, long carbtime, final Treatment t) { if (!isConnected()) return false; if (BolusProgressDialog.stopPressed) return false; - bolusingTreatment = t; + mBolusingTreatment = t; MsgBolusStart start = new MsgBolusStart(amount); MsgBolusStop stop = new MsgBolusStop(amount, t); if (carbs > 0) { - mSerialIOThread.sendMessage(new MsgSetCarbsEntry(System.currentTimeMillis(), carbs)); + mSerialIOThread.sendMessage(new MsgSetCarbsEntry(carbtime, carbs)); } MsgBolusProgress progress = new MsgBolusProgress(amount, t); // initialize static variables @@ -380,37 +274,21 @@ public class DanaRKoreanExecutionService extends Service { return false; } while (!stop.stopped && !start.failed) { - waitMsec(100); + SystemClock.sleep(100); if ((System.currentTimeMillis() - progress.lastReceive) > 15 * 1000L) { // if i didn't receive status for more than 15 sec expecting broken comm stop.stopped = true; stop.forced = true; log.debug("Communication stopped"); } } - waitMsec(300); + SystemClock.sleep(300); - bolusingTreatment = null; + mBolusingTreatment = null; ConfigBuilderPlugin.getCommandQueue().readStatus("bolusOK", null); return true; } - public void bolusStop() { - if (Config.logDanaBTComm) - log.debug("bolusStop >>>>> @ " + (bolusingTreatment == null ? "" : bolusingTreatment.insulin)); - MsgBolusStop stop = new MsgBolusStop(); - stop.forced = true; - if (isConnected()) { - mSerialIOThread.sendMessage(stop); - while (!stop.stopped) { - mSerialIOThread.sendMessage(stop); - waitMsec(200); - } - } else { - stop.stopped = true; - } - } - public boolean carbsEntry(int amount) { if (!isConnected()) return false; MsgSetCarbsEntry msg = new MsgSetCarbsEntry(System.currentTimeMillis(), amount); @@ -418,51 +296,9 @@ public class DanaRKoreanExecutionService extends Service { return true; } - public PumpEnactResult loadHistory(byte type) { - PumpEnactResult result = new PumpEnactResult(); - if (!isConnected()) return result; - MessageBase msg = null; - switch (type) { - case RecordTypes.RECORD_TYPE_ALARM: - msg = new MsgHistoryAlarm(); - break; - case RecordTypes.RECORD_TYPE_BASALHOUR: - msg = new MsgHistoryBasalHour(); - break; - case RecordTypes.RECORD_TYPE_BOLUS: - msg = new MsgHistoryBolus(); - break; - case RecordTypes.RECORD_TYPE_CARBO: - msg = new MsgHistoryCarbo(); - break; - case RecordTypes.RECORD_TYPE_DAILY: - msg = new MsgHistoryDailyInsulin(); - break; - case RecordTypes.RECORD_TYPE_ERROR: - msg = new MsgHistoryError(); - break; - case RecordTypes.RECORD_TYPE_GLUCOSE: - msg = new MsgHistoryGlucose(); - break; - case RecordTypes.RECORD_TYPE_REFILL: - msg = new MsgHistoryRefill(); - break; - case RecordTypes.RECORD_TYPE_SUSPEND: - msg = new MsgHistorySuspend(); - break; - } - MsgHistoryDone done = new MsgHistoryDone(); - mSerialIOThread.sendMessage(new MsgPCCommStart()); - waitMsec(400); - mSerialIOThread.sendMessage(msg); - while (!done.received && mRfcommSocket.isConnected()) { - waitMsec(100); - } - waitMsec(200); - mSerialIOThread.sendMessage(new MsgPCCommStop()); - result.success = true; - result.comment = "OK"; - return result; + @Override + public boolean highTempBasal(int percent) { + return false; } public boolean updateBasalsInPump(final Profile profile) { @@ -471,13 +307,10 @@ public class DanaRKoreanExecutionService extends Service { double[] basal = DanaRPump.buildDanaRProfileRecord(profile); MsgSetSingleBasalProfile msgSet = new MsgSetSingleBasalProfile(basal); mSerialIOThread.sendMessage(msgSet); - danaRPump.lastSettingsRead = new Date(0); // force read full settings + mDanaRPump.lastSettingsRead = 0; // force read full settings getPumpStatus(); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); return true; } - private void waitMsec(long msecs) { - SystemClock.sleep(msecs); - } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java index cfdbdeb5cd..9978880e08 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java @@ -348,7 +348,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, @Nullable @Override public ProfileStore getProfile() { - if (pump.lastSettingsRead.getTime() == 0) + if (pump.lastSettingsRead == 0) return null; // no info now return pump.createConvertedProfile(); } @@ -367,7 +367,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, @Override public boolean isInitialized() { - return pump.lastConnection.getTime() > 0 && pump.maxBasal > 0; + return pump.lastConnection > 0 && pump.maxBasal > 0; } @Override @@ -438,7 +438,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, @Override public Date lastDataTime() { - return pump.lastConnection; + return new Date(pump.lastConnection); } @Override @@ -753,7 +753,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, @Override public JSONObject getJSONStatus() { - if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) { + if (pump.lastConnection + 5 * 60 * 1000L < System.currentTimeMillis()) { return null; } JSONObject pumpjson = new JSONObject(); @@ -812,8 +812,8 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, @Override public String shortStatus(boolean veryShort) { String ret = ""; - if (pump.lastConnection.getTime() != 0) { - Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime(); + if (pump.lastConnection != 0) { + Long agoMsec = System.currentTimeMillis() - pump.lastConnection; int agoMin = (int) (agoMsec / 60d / 1000d); ret += "LastConn: " + agoMin + " minago\n"; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java index 7790257640..1a1f74b645 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java @@ -131,8 +131,8 @@ public class DanaRSService extends Service { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingtempbasalstatus))); bleComm.sendMessage(new DanaRS_Packet_Basal_Get_Temporary_Basal_State()); - Date now = new Date(); - if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !MainApp.getSpecificPlugin(DanaRSPlugin.class).isInitialized()) { + long now = System.currentTimeMillis(); + if (danaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRSPlugin.class).isInitialized()) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpsettings))); bleComm.sendMessage(new DanaRS_Packet_General_Get_Shipping_Information()); // serial no bleComm.sendMessage(new DanaRS_Packet_General_Get_Pump_Check()); // firmware @@ -357,7 +357,7 @@ public class DanaRSService extends Service { bleComm.sendMessage(msgSet); DanaRS_Packet_Basal_Set_Profile_Number msgActivate = new DanaRS_Packet_Basal_Set_Profile_Number(0); bleComm.sendMessage(msgActivate); - danaRPump.lastSettingsRead = new Date(0); // force read full settings + danaRPump.lastSettingsRead = 0; // force read full settings getPumpStatus(); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); return true; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java index 3e1aca22e0..34a5b2381b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java @@ -5,68 +5,31 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; -import android.support.annotation.Nullable; import com.squareup.otto.Subscribe; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; -import java.util.Objects; - -import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventAppExit; -import info.nightscout.androidaps.interfaces.ConstraintsInterface; -import info.nightscout.androidaps.interfaces.DanaRInterface; -import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpDescription; -import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; -import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; -import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; -import info.nightscout.androidaps.plugins.PumpDanaR.DanaRFragment; -import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; +import info.nightscout.androidaps.plugins.PumpDanaR.AbstractDanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaRv2.services.DanaRv2ExecutionService; -import info.nightscout.utils.DateUtil; -import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.Round; import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. */ -public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface { - private static Logger log = LoggerFactory.getLogger(DanaRv2Plugin.class); - - @Override - public String getFragmentClass() { - return DanaRFragment.class.getName(); - } - - private static boolean fragmentPumpEnabled = false; - private static boolean fragmentProfileEnabled = false; - private static boolean fragmentPumpVisible = true; - - private static DanaRv2ExecutionService sExecutionService; - +public class DanaRv2Plugin extends AbstractDanaRPlugin { private static DanaRv2Plugin plugin = null; @@ -76,11 +39,10 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface, return plugin; } - private static DanaRPump pump = DanaRPump.getInstance(); - - private static PumpDescription pumpDescription = new PumpDescription(); - private DanaRv2Plugin() { + log = LoggerFactory.getLogger(DanaRv2Plugin.class); + useExtendedBoluses = false; + Context context = MainApp.instance().getApplicationContext(); Intent intent = new Intent(context, DanaRv2ExecutionService.class); context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); @@ -134,78 +96,11 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface, } // Plugin base interface - @Override - public int getType() { - return PluginBase.PUMP; - } - @Override public String getName() { return MainApp.instance().getString(R.string.danarv2pump); } - @Override - public String getNameShort() { - String name = MainApp.sResources.getString(R.string.danarpump_shortname); - if (!name.trim().isEmpty()) { - //only if translation exists - return name; - } - // use long name as fallback - return getName(); - } - - @Override - public boolean isEnabled(int type) { - if (type == PluginBase.PROFILE) return fragmentProfileEnabled && fragmentPumpEnabled; - else if (type == PluginBase.PUMP) return fragmentPumpEnabled; - else if (type == PluginBase.CONSTRAINTS) return fragmentPumpEnabled; - return false; - } - - @Override - public boolean isVisibleInTabs(int type) { - if (type == PluginBase.PROFILE || type == PluginBase.CONSTRAINTS) return false; - else if (type == PluginBase.PUMP) return fragmentPumpVisible; - return false; - } - - @Override - public boolean canBeHidden(int type) { - return true; - } - - @Override - public boolean hasFragment() { - return true; - } - - @Override - public boolean showInList(int type) { - return type == PUMP; - } - - @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { - if (type == PluginBase.PROFILE) - fragmentProfileEnabled = fragmentEnabled; - else if (type == PluginBase.PUMP) - fragmentPumpEnabled = fragmentEnabled; - // if pump profile was enabled need to switch to another too - if (type == PluginBase.PUMP && !fragmentEnabled && fragmentProfileEnabled) { - setFragmentEnabled(PluginBase.PROFILE, false); - setFragmentVisible(PluginBase.PROFILE, false); - NSProfilePlugin.getPlugin().setFragmentEnabled(PluginBase.PROFILE, true); - NSProfilePlugin.getPlugin().setFragmentVisible(PluginBase.PROFILE, true); - } - } - - @Override - public void setFragmentVisible(int type, boolean fragmentVisible) { - if (type == PluginBase.PUMP) - fragmentPumpVisible = fragmentVisible; - } - @Override public int getPreferencesId() { return R.xml.pref_danarv2; @@ -218,86 +113,10 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface, @Override public boolean isInitialized() { - return pump.lastConnection.getTime() > 0 && pump.maxBasal > 0; - } - - @Override - public boolean isSuspended() { - return pump.pumpSuspended; - } - - @Override - public boolean isBusy() { - if (sExecutionService == null) return false; - return sExecutionService.isConnected() || sExecutionService.isConnecting(); + return pump.lastConnection > 0 && pump.maxBasal > 0; } // Pump interface - @Override - public PumpEnactResult setNewBasalProfile(Profile profile) { - PumpEnactResult result = new PumpEnactResult(); - - if (sExecutionService == null) { - log.error("setNewBasalProfile sExecutionService is null"); - result.comment = "setNewBasalProfile sExecutionService is null"; - return result; - } - if (!isInitialized()) { - log.error("setNewBasalProfile not initialized"); - Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notification)); - result.comment = MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet); - return result; - } else { - MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); - } - if (!sExecutionService.updateBasalsInPump(profile)) { - Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.sResources.getString(R.string.failedupdatebasalprofile), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notification)); - result.comment = MainApp.sResources.getString(R.string.failedupdatebasalprofile); - return result; - } else { - MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); - MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE)); - Notification notification = new Notification(Notification.PROFILE_SET_OK, MainApp.sResources.getString(R.string.profile_set_ok), Notification.INFO, 60); - MainApp.bus().post(new EventNewNotification(notification)); - result.success = true; - result.enacted = true; - result.comment = "OK"; - return result; - } - } - - @Override - public boolean isThisProfileSet(Profile profile) { - if (!isInitialized()) - return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS - if (pump.pumpProfiles == null) - return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS - int basalValues = pump.basal48Enable ? 48 : 24; - int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60; - for (int h = 0; h < basalValues; h++) { - Double pumpValue = pump.pumpProfiles[pump.activeProfile][h]; - Double profileValue = profile.getBasal((Integer) (h * basalIncrement)); - if (profileValue == null) return true; - if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) { - log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); - return false; - } - } - return true; - } - - @Override - public Date lastDataTime() { - return pump.lastConnection; - } - - @Override - public double getBaseBasalRate() { - return pump.currentBasal; - } - @Override public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); @@ -513,49 +332,6 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface, return result; } - @Override - public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - insulin = configBuilderPlugin.applyBolusConstraints(insulin); - // needs to be rounded - int durationInHalfHours = Math.max(durationInMinutes / 30, 1); - insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep); - - PumpEnactResult result = new PumpEnactResult(); - ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); - if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) { - result.enacted = false; - result.success = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - result.duration = pump.extendedBolusRemainingMinutes; - result.absolute = pump.extendedBolusAbsoluteRate; - result.isPercent = false; - result.isTempCancel = false; - if (Config.logPumpActions) - log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin); - return result; - } - boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours); - if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) { - result.enacted = true; - result.success = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - result.isTempCancel = false; - result.duration = pump.extendedBolusRemainingMinutes; - result.absolute = pump.extendedBolusAbsoluteRate; - result.bolusDelivered = pump.extendedBolusAmount; - result.isPercent = false; - if (Config.logPumpActions) - log.debug("setExtendedBolus: OK"); - return result; - } - result.enacted = false; - result.success = false; - result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly); - log.error("setExtendedBolus: Failed to extended bolus"); - return result; - } - @Override public PumpEnactResult cancelTempBasal(boolean force) { PumpEnactResult result = new PumpEnactResult(); @@ -581,257 +357,8 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface, } } - @Override - public PumpEnactResult cancelExtendedBolus() { - PumpEnactResult result = new PumpEnactResult(); - ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); - if (runningEB != null) { - sExecutionService.extendedBolusStop(); - result.enacted = true; - result.isTempCancel = true; - } - if (!pump.isExtendedInProgress) { - result.success = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - if (Config.logPumpActions) - log.debug("cancelExtendedBolus: OK"); - return result; - } else { - result.success = false; - result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly); - log.error("cancelExtendedBolus: Failed to cancel extended bolus"); - return result; - } - } - - @Override - public void connect(String from) { - if (sExecutionService != null) { - sExecutionService.connect(from); - pumpDescription.basalStep = pump.basalStep; - pumpDescription.bolusStep = pump.bolusStep; - } - } - - @Override - public boolean isConnected() { - return sExecutionService != null && sExecutionService.isConnected(); - } - - @Override - public boolean isConnecting() { - return sExecutionService != null && sExecutionService.isConnecting(); - } - - @Override - public void disconnect(String from) { - if (sExecutionService != null) sExecutionService.disconnect(from); - } - - @Override - public void stopConnecting() { - if (sExecutionService != null) sExecutionService.stopConnecting(); - } - - @Override - public void getPumpStatus() { - if (sExecutionService != null) sExecutionService.getPumpStatus(); - } - - @Override - public JSONObject getJSONStatus() { - if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) { - return null; - } - JSONObject pumpjson = new JSONObject(); - JSONObject battery = new JSONObject(); - JSONObject status = new JSONObject(); - JSONObject extended = new JSONObject(); - try { - battery.put("percent", pump.batteryRemaining); - status.put("status", pump.pumpSuspended ? "suspended" : "normal"); - status.put("timestamp", DateUtil.toISOString(pump.lastConnection)); - extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION); - extended.put("PumpIOB", pump.iob); - if (pump.lastBolusTime.getTime() != 0) { - extended.put("LastBolus", pump.lastBolusTime.toLocaleString()); - extended.put("LastBolusAmount", pump.lastBolusAmount); - } - TemporaryBasal tb = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); - if (tb != null) { - extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis())); - extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date)); - extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes()); - } - ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); - if (eb != null) { - extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate()); - extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date)); - extended.put("ExtendedBolusRemaining", eb.getPlannedRemainingMinutes()); - } - extended.put("BaseBasalRate", getBaseBasalRate()); - try { - extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName()); - } catch (Exception e) { - } - - pumpjson.put("battery", battery); - pumpjson.put("status", status); - pumpjson.put("extended", extended); - pumpjson.put("reservoir", (int) pump.reservoirRemainingUnits); - pumpjson.put("clock", DateUtil.toISOString(new Date())); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return pumpjson; - } - - @Override - public String deviceID() { - return pump.serialNumber; - } - - @Override - public PumpDescription getPumpDescription() { - return pumpDescription; - } - - /** - * DanaR interface - */ - - @Override - public PumpEnactResult loadHistory(byte type) { - return sExecutionService.loadHistory(type); - } - @Override public PumpEnactResult loadEvents() { return sExecutionService.loadEvents(); } - - /** - * Constraint interface - */ - - @Override - public boolean isLoopEnabled() { - return true; - } - - @Override - public boolean isClosedModeEnabled() { - return true; - } - - @Override - public boolean isAutosensModeEnabled() { - return true; - } - - @Override - public boolean isAMAModeEnabled() { - return true; - } - - @Override - public boolean isSMBModeEnabled() { - return true; - } - - @SuppressWarnings("PointlessBooleanExpression") - @Override - public Double applyBasalConstraints(Double absoluteRate) { - double origAbsoluteRate = absoluteRate; - if (pump != null) { - if (absoluteRate > pump.maxBasal) { - absoluteRate = pump.maxBasal; - if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit) - log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h"); - } - } - return absoluteRate; - } - - @SuppressWarnings("PointlessBooleanExpression") - @Override - public Integer applyBasalConstraints(Integer percentRate) { - Integer origPercentRate = percentRate; - if (percentRate < 0) percentRate = 0; - if (percentRate > getPumpDescription().maxTempPercent) - percentRate = getPumpDescription().maxTempPercent; - if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit)) - log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%"); - return percentRate; - } - - @SuppressWarnings("PointlessBooleanExpression") - @Override - public Double applyBolusConstraints(Double insulin) { - double origInsulin = insulin; - if (pump != null) { - if (insulin > pump.maxBolus) { - insulin = pump.maxBolus; - if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit) - log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U"); - } - } - return insulin; - } - - @Override - public Integer applyCarbsConstraints(Integer carbs) { - return carbs; - } - - @Override - public Double applyMaxIOBConstraints(Double maxIob) { - return maxIob; - } - - @Nullable - @Override - public ProfileStore getProfile() { - if (pump.lastSettingsRead.getTime() == 0) - return null; // no info now - return pump.createConvertedProfile(); - } - - @Override - public String getUnits() { - return pump.getUnits(); - } - - @Override - public String getProfileName() { - return pump.createConvertedProfileName(); - } - - // Reply for sms communicator - public String shortStatus(boolean veryShort) { - String ret = ""; - if (pump.lastConnection.getTime() != 0) { - Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime(); - int agoMin = (int) (agoMsec / 60d / 1000d); - ret += "LastConn: " + agoMin + " minago\n"; - } - if (pump.lastBolusTime.getTime() != 0) { - ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n"; - } - if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { - ret += "Temp: " + MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n"; - } - if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n"; - } - if (!veryShort) { - ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n"; - } - ret += "IOB: " + pump.iob + "U\n"; - ret += "Reserv: " + DecimalFormatter.to0Decimal(pump.reservoirRemainingUnits) + "U\n"; - ret += "Batt: " + pump.batteryRemaining + "\n"; - return ret; - } - // TODO: daily total constraint - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java index 343a176e56..a12e2085aa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java @@ -13,13 +13,14 @@ import java.io.OutputStream; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; +import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractSerialIOThread; import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MessageHashTable_v2; import info.nightscout.utils.CRC; /** * Created by mike on 17.07.2016. */ -public class SerialIOThread extends Thread { +public class SerialIOThread extends AbstractSerialIOThread { private static Logger log = LoggerFactory.getLogger(SerialIOThread.class); private InputStream mInputStream = null; @@ -29,10 +30,10 @@ public class SerialIOThread extends Thread { private boolean mKeepRunning = true; private byte[] mReadBuff = new byte[0]; - MessageBase processedMessage; + private MessageBase processedMessage; public SerialIOThread(BluetoothSocket rfcommSocket) { - super(SerialIOThread.class.toString()); + super(); mRfCommSocket = rfcommSocket; try { @@ -138,6 +139,7 @@ public class SerialIOThread extends Thread { } } + @Override public synchronized void sendMessage(MessageBase message) { if (!mRfCommSocket.isConnected()) { log.error("Socket not connected on sendMessage"); @@ -173,6 +175,7 @@ public class SerialIOThread extends Thread { } } + @Override public void disconnect(String reason) { mKeepRunning = false; try { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java index 9869ef0895..60133d8d25 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java @@ -40,6 +40,7 @@ public class MsgCheckValue_v2 extends MessageBase { pump.protocol = intFromBuff(bytes, 1, 1); pump.productCode = intFromBuff(bytes, 2, 1); if (pump.model != DanaRPump.EXPORT_MODEL) { + pump.lastConnection = 0; Notification notification = new Notification(Notification.WRONG_DRIVER, MainApp.sResources.getString(R.string.pumpdrivercorrected), Notification.NORMAL); MainApp.bus().post(new EventNewNotification(notification)); MainApp.getSpecificPlugin(DanaRPlugin.class).disconnect("Wrong Model"); @@ -48,7 +49,7 @@ public class MsgCheckValue_v2 extends MessageBase { MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginBase.PUMP, true); MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentEnabled(PluginBase.PUMP, false); MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentVisible(PluginBase.PUMP, false); - DanaRPump.getInstance().lastConnection = new Date(0); // mark not initialized + DanaRPump.getInstance().lastConnection = 0; // mark not initialized //If profile coming from pump, switch it as well if(MainApp.getSpecificPlugin(DanaRPlugin.class).isEnabled(PluginBase.PROFILE)){ @@ -63,6 +64,7 @@ public class MsgCheckValue_v2 extends MessageBase { } if (pump.protocol != 2) { + pump.lastConnection = 0; Notification notification = new Notification(Notification.WRONG_DRIVER, MainApp.sResources.getString(R.string.pumpdrivercorrected), Notification.NORMAL); MainApp.bus().post(new EventNewNotification(notification)); DanaRKoreanPlugin.getPlugin().disconnect("Wrong Model"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java index 71a2f9ac79..81b5837511 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java @@ -1,52 +1,66 @@ package info.nightscout.androidaps.plugins.PumpDanaRv2.services; -import android.app.Service; -import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothSocket; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; import android.content.IntentFilter; import android.os.Binder; -import android.os.IBinder; import android.os.SystemClock; import com.squareup.otto.Subscribe; -import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Date; -import java.util.Set; -import java.util.UUID; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; -import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.*; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusProgress; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStart; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStartWithSpeed; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStop; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetActivateBasalProfile; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetBasalProfile; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetCarbsEntry; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetExtendedBolusStart; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetExtendedBolusStop; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStart; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStop; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTime; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingActiveProfile; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingBasal; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingGlucose; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMaxValues; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMeal; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatios; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatiosAll; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingPumpTime; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingShippingInfo; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatus; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBasic; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; +import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractDanaRExecutionService; import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; import info.nightscout.androidaps.plugins.PumpDanaRv2.SerialIOThread; +import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgCheckValue_v2; import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgHistoryEvents_v2; import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgSetAPSTempBasalStart_v2; import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgSetHistoryEntry_v2; -import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgCheckValue_v2; import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgStatusBolusExtended_v2; import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgStatusTempBasal_v2; import info.nightscout.androidaps.queue.Callback; @@ -54,47 +68,16 @@ import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; import info.nightscout.utils.ToastUtils; -public class DanaRv2ExecutionService extends Service { - private static Logger log = LoggerFactory.getLogger(DanaRv2ExecutionService.class); - - private String devName; - - private SerialIOThread mSerialIOThread; - private BluetoothSocket mRfcommSocket; - private BluetoothDevice mBTDevice; - - private IBinder mBinder = new LocalBinder(); - - private DanaRPump danaRPump; - private Treatment bolusingTreatment = null; - - private static Boolean connectionInProgress = false; - - private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); +public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { private long lastHistoryFetched = 0; - private BroadcastReceiver receiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - String action = intent.getAction(); - if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { - log.debug("Device was disconnected " + device.getName());//Device was disconnected - if (mBTDevice != null && mBTDevice.getName() != null && mBTDevice.getName().equals(device.getName())) { - if (mSerialIOThread != null) { - mSerialIOThread.disconnect("BT disconnection broadcast"); - } - MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED)); - } - } - } - }; - public DanaRv2ExecutionService() { + log = LoggerFactory.getLogger(DanaRv2ExecutionService.class); + mBinder = new LocalBinder(); + registerBus(); MainApp.instance().getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED)); - danaRPump = DanaRPump.getInstance(); } public class LocalBinder extends Binder { @@ -103,17 +86,6 @@ public class DanaRv2ExecutionService extends Service { } } - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - - return START_STICKY; - } - private void registerBus() { try { MainApp.bus().unregister(this); @@ -138,35 +110,28 @@ public class DanaRv2ExecutionService extends Service { log.debug("EventAppExit finished"); } - public boolean isConnected() { - return mRfcommSocket != null && mRfcommSocket.isConnected(); - } - - public boolean isConnecting() { - return connectionInProgress; - } - - public void disconnect(String from) { + @Subscribe + public void onStatusEvent(final EventPreferenceChange pch) { if (mSerialIOThread != null) - mSerialIOThread.disconnect(from); + mSerialIOThread.disconnect("EventPreferenceChange"); } - public void connect(String from) { - if (danaRPump.password != -1 && danaRPump.password != SP.getInt(R.string.key_danar_password, -1)) { + public void connect() { + if (mDanaRPump.password != -1 && mDanaRPump.password != SP.getInt(R.string.key_danar_password, -1)) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.wrongpumppassword), R.raw.error); return; } - if (connectionInProgress) + if (mConnectionInProgress) return; new Thread(new Runnable() { @Override public void run() { - connectionInProgress = true; + mConnectionInProgress = true; getBTSocketForSelectedPump(); if (mRfcommSocket == null || mBTDevice == null) { - connectionInProgress = false; + mConnectionInProgress = false; return; // Device not found } @@ -187,48 +152,11 @@ public class DanaRv2ExecutionService extends Service { MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTED, 0)); } - connectionInProgress = false; + mConnectionInProgress = false; } }).start(); } - public void stopConnecting() { - if (mSerialIOThread != null) - mSerialIOThread.disconnect("stopConnecting"); - } - - private void getBTSocketForSelectedPump() { - devName = SP.getString(MainApp.sResources.getString(R.string.key_danar_bt_name), ""); - BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - - if (bluetoothAdapter != null) { - Set bondedDevices = bluetoothAdapter.getBondedDevices(); - - for (BluetoothDevice device : bondedDevices) { - if (devName.equals(device.getName())) { - mBTDevice = device; - try { - mRfcommSocket = mBTDevice.createRfcommSocketToServiceRecord(SPP_UUID); - } catch (IOException e) { - log.error("Error creating socket: ", e); - } - break; - } - } - } else { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.nobtadapter)); - } - if (mBTDevice == null) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.devicenotfound)); - } - } - - @Subscribe - public void onStatusEvent(final EventPreferenceChange pch) { - if (mSerialIOThread != null) - mSerialIOThread.disconnect("EventPreferenceChange"); - } - public void getPumpStatus() { try { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpstatus))); @@ -238,7 +166,7 @@ public class DanaRv2ExecutionService extends Service { MsgStatusBolusExtended_v2 exStatusMsg = new MsgStatusBolusExtended_v2(); MsgCheckValue_v2 checkValue = new MsgCheckValue_v2(); - if (danaRPump.isNewPump) { + if (mDanaRPump.isNewPump) { mSerialIOThread.sendMessage(checkValue); if (!checkValue.received) { return; @@ -253,8 +181,8 @@ public class DanaRv2ExecutionService extends Service { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingextendedbolusstatus))); mSerialIOThread.sendMessage(exStatusMsg); - Date now = new Date(); - if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !MainApp.getSpecificPlugin(DanaRv2Plugin.class).isInitialized()) { + long now = System.currentTimeMillis(); + if (mDanaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRv2Plugin.class).isInitialized()) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpsettings))); mSerialIOThread.sendMessage(new MsgSettingShippingInfo()); mSerialIOThread.sendMessage(new MsgSettingActiveProfile()); @@ -268,28 +196,28 @@ public class DanaRv2ExecutionService extends Service { mSerialIOThread.sendMessage(new MsgSettingProfileRatiosAll()); MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumptime))); mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - long timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; + long timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; log.debug("Pump time difference: " + timeDiff + " seconds"); if (Math.abs(timeDiff) > 10) { mSerialIOThread.sendMessage(new MsgSetTime(new Date())); mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; + timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; log.debug("Pump time difference: " + timeDiff + " seconds"); } - danaRPump.lastSettingsRead = now; + mDanaRPump.lastSettingsRead = now; } loadEvents(); - danaRPump.lastConnection = now; + mDanaRPump.lastConnection = now; MainApp.bus().post(new EventDanaRNewStatus()); MainApp.bus().post(new EventInitializationChanged()); NSUpload.uploadDeviceStatus(); - if (danaRPump.dailyTotalUnits > danaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { - log.debug("Approaching daily limit: " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits); + if (mDanaRPump.dailyTotalUnits > mDanaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { + log.debug("Approaching daily limit: " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits); Notification reportFail = new Notification(Notification.APPROACHING_DAILY_LIMIT, MainApp.sResources.getString(R.string.approachingdailylimit), Notification.URGENT); MainApp.bus().post(new EventNewNotification(reportFail)); - NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits + "U"); + NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits + "U"); } } catch (Exception e) { log.error("Unhandled exception", e); @@ -299,10 +227,10 @@ public class DanaRv2ExecutionService extends Service { public boolean tempBasal(int percent, int durationInHours) { if (!isConnected()) return false; - if (danaRPump.isTempBasalInProgress) { + if (mDanaRPump.isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); - waitMsec(500); + SystemClock.sleep(500); } MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.settingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStart(percent, durationInHours)); @@ -314,10 +242,10 @@ public class DanaRv2ExecutionService extends Service { public boolean highTempBasal(int percent) { if (!isConnected()) return false; - if (danaRPump.isTempBasalInProgress) { + if (mDanaRPump.isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); - waitMsec(500); + SystemClock.sleep(500); } MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.settingtempbasal))); mSerialIOThread.sendMessage(new MsgSetAPSTempBasalStart_v2(percent)); @@ -362,7 +290,7 @@ public class DanaRv2ExecutionService extends Service { if (BolusProgressDialog.stopPressed) return false; MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.startingbolus))); - bolusingTreatment = t; + mBolusingTreatment = t; final int preferencesSpeed = SP.getInt(R.string.key_danars_bolusspeed, 0); MessageBase start; if (preferencesSpeed == 0) @@ -390,7 +318,7 @@ public class DanaRv2ExecutionService extends Service { return false; } while (!stop.stopped && !start.failed) { - waitMsec(100); + SystemClock.sleep(100); if ((System.currentTimeMillis() - progress.lastReceive) > 15 * 1000L) { // if i didn't receive status for more than 15 sec expecting broken comm stop.stopped = true; stop.forced = true; @@ -403,7 +331,7 @@ public class DanaRv2ExecutionService extends Service { bolusingEvent.t = t; bolusingEvent.percent = 99; - bolusingTreatment = null; + mBolusingTreatment = null; int speed = 12; switch (preferencesSpeed) { case 0: @@ -440,14 +368,14 @@ public class DanaRv2ExecutionService extends Service { public void bolusStop() { if (Config.logDanaBTComm) - log.debug("bolusStop >>>>> @ " + (bolusingTreatment == null ? "" : bolusingTreatment.insulin)); + log.debug("bolusStop >>>>> @ " + (mBolusingTreatment == null ? "" : mBolusingTreatment.insulin)); MsgBolusStop stop = new MsgBolusStop(); stop.forced = true; if (isConnected()) { mSerialIOThread.sendMessage(stop); while (!stop.stopped) { mSerialIOThread.sendMessage(stop); - waitMsec(200); + SystemClock.sleep(200); } } else { stop.stopped = true; @@ -464,57 +392,10 @@ public class DanaRv2ExecutionService extends Service { return true; } - public PumpEnactResult loadHistory(byte type) { - PumpEnactResult result = new PumpEnactResult(); - if (!isConnected()) return result; - MessageBase msg = null; - switch (type) { - case RecordTypes.RECORD_TYPE_ALARM: - msg = new MsgHistoryAlarm(); - break; - case RecordTypes.RECORD_TYPE_BASALHOUR: - msg = new MsgHistoryBasalHour(); - break; - case RecordTypes.RECORD_TYPE_BOLUS: - msg = new MsgHistoryBolus(); - break; - case RecordTypes.RECORD_TYPE_CARBO: - msg = new MsgHistoryCarbo(); - break; - case RecordTypes.RECORD_TYPE_DAILY: - msg = new MsgHistoryDailyInsulin(); - break; - case RecordTypes.RECORD_TYPE_ERROR: - msg = new MsgHistoryError(); - break; - case RecordTypes.RECORD_TYPE_GLUCOSE: - msg = new MsgHistoryGlucose(); - break; - case RecordTypes.RECORD_TYPE_REFILL: - msg = new MsgHistoryRefill(); - break; - case RecordTypes.RECORD_TYPE_SUSPEND: - msg = new MsgHistorySuspend(); - break; - } - MsgHistoryDone done = new MsgHistoryDone(); - mSerialIOThread.sendMessage(new MsgPCCommStart()); - waitMsec(400); - mSerialIOThread.sendMessage(msg); - while (!done.received && mRfcommSocket.isConnected()) { - waitMsec(100); - } - waitMsec(200); - mSerialIOThread.sendMessage(new MsgPCCommStop()); - result.success = true; - result.comment = "OK"; - return result; - } - public PumpEnactResult loadEvents() { if (!isConnected()) return new PumpEnactResult().success(false); - waitMsec(300); + SystemClock.sleep(300); MsgHistoryEvents_v2 msg; if (lastHistoryFetched == 0) { msg = new MsgHistoryEvents_v2(); @@ -525,9 +406,9 @@ public class DanaRv2ExecutionService extends Service { } mSerialIOThread.sendMessage(msg); while (!msg.done && mRfcommSocket.isConnected()) { - waitMsec(100); + SystemClock.sleep(100); } - waitMsec(200); + SystemClock.sleep(200); if (MsgHistoryEvents_v2.lastEventTimeLoaded != 0) lastHistoryFetched = MsgHistoryEvents_v2.lastEventTimeLoaded - 45 * 60 * 1000L; //always load last 45 min; else @@ -543,13 +424,10 @@ public class DanaRv2ExecutionService extends Service { mSerialIOThread.sendMessage(msgSet); MsgSetActivateBasalProfile msgActivate = new MsgSetActivateBasalProfile((byte) 0); mSerialIOThread.sendMessage(msgActivate); - danaRPump.lastSettingsRead = new Date(0); // force read full settings + mDanaRPump.lastSettingsRead = 0; // force read full settings getPumpStatus(); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); return true; } - private void waitMsec(long msecs) { - SystemClock.sleep(msecs); - } } From b11e30139144591e3e888866434d90d2e9b4a10a Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 29 Jan 2018 20:05:16 +0100 Subject: [PATCH 11/22] ES translations --- app/src/main/res/values-es/strings.xml | 463 +++++++++++++++++++++++-- 1 file changed, 438 insertions(+), 25 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 988a92928d..d3f1c23744 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -296,7 +296,7 @@ Corr Loop Inactivo Bolo Comida - Valor %s fuera de limites + Valor %s fuera de limites Botón Texto: Carbs: Validar: @@ -314,7 +314,7 @@ Fallo inicio basal temporal Basal temporal %.2fU/h para %d min iniciada correctamente Permitir comandos SMS remotos - Para parar basal temporal responder con codigo %s + Para parar basal temporal responder con codigo %s AndroidAPS iniciado Español NS solo subida (sinc. inactiva) @@ -326,27 +326,25 @@ Comando desconocido o respuesta incorrecta ¡Por favor asegurar que la cantidad coincide con la especificación del set de infusión! Para iniciar basal %.2fU/h responder con código %s - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " + "acciones" + "bomba virtual" + "tratamientos" + " objectivos temporales" + "objtemp" + "comunicacíon sms" + "Profil simple" + "Profiles" + "General" + "Objectivos" + "OAPS" + "LOOP" + "LP" + DANA + "conf" + CP Actividad - Por favo reinicia el teléfono o AndroidAPS desde ajustes de sistema, sino AndroidAPS no guardara registros (importantes para trazar y verificar que el algoritmo funciona correctamente) - Matriz de %d elementos. Valor actual: + Por favor reinicia el teléfono o AndroidAPS desde ajustes de sistema, sino AndroidAPS no guardara registros (importantes para trazar y verificar que el algoritmo funciona correctamente) + Matriz de %d elementos. Valor actual: Ratio Basal: Valor basal menor del mínimo. Perfil no fijado. Perfil Base @@ -363,7 +361,7 @@ Media Larga Delta Marca BAJO Batería Baja - %dmin antes + %dmin antes Usar característica AMA autosens Datos Autosens Factor porcentual para multiplicar el perfil base @@ -379,15 +377,430 @@ Media corta delta Bolo: Último BG: - %dmin antes + %dmin antes Bolo %.2fU enviado correctamente Rango Objetivo: Unidades: Sólo se permiten caracteres numéricos - Sólo se permiten dígitos en el rango %1$s - %2$s + Sólo se permiten dígitos en el rango %1$s - %2$s Este campo no puede estar vacío Número de teléfono inválido Esperando bomba Italian AndroidAPS + hollandes + Griego + Ruso + Sueco + Max U/h para el perfil base + "Max IOB basal OpenAPs puede emitir " + Para enviar calibracion %.2f responder con codigo %s + Entregaré %.2fU + Duración de acitividad de insulina + Errores + habilitar funciones adicionales para uso durante el día como SMB + %.2f limitado a %.\"f + no permitido el mando remoto + Para cancelar loop por %d minutos responde con codigo %s + Rellenar/Llenar + Llenar/Rellenar cantidad de insulina estándar + Tiempo en horas en el que el perfil será movido + mg/dl + mmol/l + DIA: + Editar Base-Basal: + Edidat Base-ISF: + Editar Base-IC: + CircadianPercentageProfile + Reloj + Abrir ajustes en reloj + Batería de la bomba descargada + DanaR Korean + BG: + MDI + MM640g + Avisos permanentes + DATOS CADUCADOS + OpenAPS AMA + Script debug + Renovar datos desde NS + DanaR Stats + Dosis diaria cumulativa + "Dosis diaria ampliada exponencialmente " + Base + Bolo + Dosis diaria + Fecha + Cuota + # Días + Peso + Probablemente impreciso usando bolo para llenar/rellenar! + Datos caducados pro favor pincha RELOAD + Basal total + Basal diaria *2 + CPP + Reloj + Tab titulo corto + Ajustes Delta + Usa siempre delta media corto en vez de delta simple + Recomendado si los datos de origen no filtrados como xDrip son inestables. + Ajustes avancados + Modelo: %02X Protocolo: %02X Codigo: %02X + Perfiles + max_daily_safety_multiplier + "Valor por defecte: 3 Esto es valor de seguridad establecido pos OpenAPS. Limita tu base al máximo de x3 de tu base máxima. No necesitas cambiar esto, pero debes tener en cuenta, que esto se esta discutiento sobre „3 x max diario; 4x actual“ pro razones de seguridad. " + current_basal_safety_multiplier + "Ajuste pro defecto: 4 Esto es la otra mitad de los ajustes de seguridad de OpenAPS y la otra mitad de \"3x max diario, 4x actual\". Esto significa, que tu base no puede ser mas alta que el numero que multiplica tu base. Esto es para evitar que las personas se encuentren en situaciones peligrosas por aumentar mucho la base sin entender el algoritmo del sistema. El ajuste por defecto es x4. La mayoría de las personas nunca tendra que cambiar estos ajustes, si no debe modificar otros ajustes en la terapia. " + autosens_max + "Ajuste por defecto: 1.2\nEsto es un multilicador para autosens (y pronto autotune) para poner un 20% limite máximo a la cota de autosens ratio, la que determina cuantos ajustes autosens puede hacer a la base, a cuanto puede ajustar ISF y a cuanto puede bajar el objective de glucosa. " + autosens_min + Ajuste pro defecto: 0.7\nEl otro lade de limitaciones de seguridad de autosens, limitando a cuanto puede bajar la base y a cuanto puede subir ISF y BG objectivos. + autosens_adjust_targets + Ajuste pro defcto: true\nEsto se usa para permitir autosens a ajustar objectivos BG en addicion a ISF y bases. + bolussnooze_dia_divisor + Ajuste pro defecto: 2 \nDormir bolo es iniciado después de proveder un bolo para comida, así el loop no interactuará con low temps cuando acabas de comer. El ajuste pro defecto es 2; quiere decir con el DIA de 3 h el bolo será dormido por fases por 1.5 h (3DIA/2). + 5_min_carb_impact + "Ajustes pro defecto: 3.0\nEsto es un ajuste pro defecto para la absorcion de carbohidratos pro 5 minutos. Por defecto se espera 3mg/dl/5min. Esto afecta la velocidad de reduccion de COB y cuanta absorcion se usa para calcular el BG futuro previsto, si la glucosa diminua mas de lo previsto o aumenta mas de lo previsto. " + "Atención!\nNormalment no tienes que editar los valores a continuacion. Por favor PINCHA AQUI y LEE el texto y PROCURA ENTENDER antes de cambiar alguno de los valores. " + http://openaps.readthedocs.io/en/latest/docs/walkthrough/phase-3/beyond-low-glucose-suspend.html + numero de telefonp incorrecto + Copiar al Clipboard + Copiado al clipboard + mostrar log + Calibracion + Calibracion + Mandar calibracion %.lf a xDrip? + xDrip+ no instalado + Calibracion mandada a xDrip + Calibracion remota no admitida + Mandar calibracion tiene que ser activada en xDrip. + xDrip no recibe calibraciones + no mostrar otra vez + Bomba parada. Pincha para aktualizar + bomba parada + recibir estado de bomba + iniciando base temporal + parando base temporal + iniciando bolo prolongado + parando bolo prolongado + actualizando cuota base + Desconectando + Efectuando + Ajustes bomba virtual + Subiendo estado a NS + Contrasena invalida + Contrasena para ajustes + desbloquear ajustes + llegando al limite de insulina diario + NSClient + NSCI + URL: + Autoscroll + Reiniciar + NSClient + Nightscout URL + Indica Nightscout URL + NS API secret + NS API secret + Indica NS API secret (min 12 chars) + Nombre aparato + Indica nombre aparato + Se usara para enteredBy field + entregar ahora + borrar cola + mostrar cola + Cola: + Estado: + Pausado + Borrar log + NSCLIENT no tiene derecho para editar. API secret incorrecto? + Ajustes reloj + mostrar detalles IOB + Separar IOB en bolo y base en el reloj + sin efecto - por favor controlar en móvil + no disponible + Edad paciente + Menor de edad + Adolescente + Adulto + Por favor elige edad del paciente para emplear limites de seguridad + Glimp + Aparato parece no soportar optimisacion de bateria whitelisting! + Por favor permita Permission + %s necesita optimisacion de bateria whitelisting para funcionar bien + Loop desactivado + desactivado (%d m) + Superbolus (%d m) + Loop menu + Desactivar loop por 1h + Desactivar loop por 2h + Desactivar loop por 3h + Desactivar loop por 10 h + Desconectar bomba por 30 min + Desconectar bomba por 1 h + Desconectar bomba por 2 h + Desconectar bomba por 3 h + Desconectar bomba por 10 h + Reiniciar + duracion incorrecta + Loop desactivado + Loop reiniciado + Tendencia 15 min + COB + Superbolo + Indica app start en NS + Aplicacion existente para aplicar ajustes. + DanaRv2 + Insulina + Insulina acción rápida + Novorapid, Novolog, Humalog + Fiasp + INS + Insulina acción rápida prolongada + activar superbolo en wizard + Activar función superbolo en wizard. No lo actives hasta que hayas aprendido lo que realmente hace. PUEDE CAUSAR SOBREDOSIS DE INSULINA usandolo sin precaucion! + IOB + COB + PRE + BAS + Firmware + Estado de bluetooth + Sobre + "Falta permitir SMS " + DEV + xDrip Status (reloj) + xDrip Statusline (reloj) + xds + Mostrar BGI + agregar BGI a status line + No upload to NS + Todos los datos mandados a NS son borrados. AAPS esta conectado to NS pero no hay cambios en NS + Nivel base + Nivel bolo + Bolo prolongado + "Objectivo temporal " + cancelar bolo prolongado + Edad sensor + Edad cánula + Edad insulina + horas + Tipo base + Falta ISF en perfil. Usando ajuste por defecto. + Falta IC en perfil. Usando ajuste por defecto. + Falta base en perfil. Usando ajuste por defecto. + "Falta objectivo en perfil. Usando ajuste por defecto. " + Perfil invalido !!! + CambioPerfil + Edad bateria bomba + Cambio bateria bomba + Opciones alama + Urgente alto + Alto + Bajo + Urgente bajo + Actualmente puesto a %f + Stale data + Urgent stale data + Stale data threshold [min] + Urgent stale data threshold [min] + Interval para autosens [h] + Horas en el pasado para detectar sensividad (tiempo de absorcion de carbohidratos no incluidos) + SEN + "Ignora evenos de cambio de perfil " + "Totos los cambios de perfil son ignorados y se usa siempre el perfil actual " + Bomba + OpenAPS + Aparato + Uploader + Deteccion sensividad + SENS + Sensitivity Oref0 + Sensitivity AAPS + Ajustes absorcion + Tiempo max absorcion comida [h] + Tiempo esperado en el que todos los carbohidratos son absorbados + mostrar bolo prolongado en % + SAGE + IAGE + CAGE + PBAGE + OAPS + UPLD + BAS + EXT + Pantalle proteccion + Cierre + Al activar autosens recuerda editar todos carbohidratos comidos. Si no, sensividad será calculada incorrectamente !!! + Sensitivity WeightedAverage + OK + Cancelar + necesita ser activado para mandar valores a la bomba! + Faltan perfiles! + Valores no guardados! + Resumen avisos + Mandar resumen de avisos como avisos de confirmacion por reloj. + Accu-Chek Combo + COMBO + Activar mensajes a otras aplicaciones (como xDrip). + Activar mensajes locales. + ACTIVITY Y FEEDBACK + CARBS Y BOLUS + CGM Y OPENAPS + PUMP + Valor base [U/h] + Duracion [min] + IOB Curve Peak Time + Peak Time [min] + Free-Peak Oref + Rapid-Acting Oref + Ultra-Rapid Oref + DIA de %s demasiado corto - usando %s! + ACTIVAR PERFIL + Fecha + INVALIDO + Esperando para conectar con bomba + Coneccion OK + Coneccion fuera de tiempo + CONECTANDO + aparato no enconrado + Deposito vacio + Alerta de control de BG + Insulina restante en deposito + DanaRS + Dana + Bomba sleccionada + Conectar bomba nueva + Velocidad bolo + Poner paso base a 0.01 U/h + Numero de serie + Porcientos + Cambio de tiepmo + Ojbectivo temporal por defecto + duracion comiendopronto + objectivo comiendopronto + duracion actividad + objectivo actividad + Prime + recibiendo estado de bolo prolongado + recibiendo estado bolo + recibiendo estado bolo temporal + recibiendo ah´justes bomba + recibiendo hora bomba + usar otra vez + Control desde reloj + editar y emitir abjectivos temp. y tratamientos por reloj + Fuera tiempo coneccion + comida + g + ]]> + kJ + En + Pr + Grasa + ]]> + Esperande terminar bolo. Faltan %d seg. + Processando + "Iniciando emisioin bolo " + Orden se esta efectuando en este momento + control de la bomba corigido + bomba no alcanzable + "Falta lectura BG " + Usa avisos del sistema para alarmas y avisos + Alarma local + Alarma si no llegan datos BG + Alarma si bomba no es alcanzable + Alarma urgente + INFO + Bluetooth + BT Watchdog + Apaga el bluetooth del móvil por un segundo si no hay coneccion con la bomba. Esto ayuda con algunos moviles con problemas de establecer coneccion bluetooth estable. + DexcomG5 App (patched) + Envias datos BG a NS + G5 upload ajustes + APK adaptada para bajar + "mostrar detalles delta " + mostrar delta con una plaza decimal mas + firmware de la bomba no apoyada + mandar BG a xDrip + En xDrip elige 640g/Eversense date source + NSClient BG + Valor base remplazado por valor mínimo + Calculacion BG + Calculacion bolo IOB + Calculacion base IOB + Calculacion tendencia + Calculacion superbolo + Si + No + Solo positivo + Solo negativo + Calculacion COB + Calculacion objectivo temporal + Loop activado + APS seleccionado + NSClient tiene permission de escribir + Modo cerrado activado + Máximo IOB puesto correctamente + BG adquirible del origen seleccionado + Valores base no asignados a las horas: %s + Perfil invalido: %s + Programando bomba para emitir bolo + Actualizar + TDDS + Estado + Actividad + Ninguna coneccnion por %d min + %d%% (%d min restan) + %.1f U (%s, %s) + Iniciando + Desconectado + Apagado por error + Apagado por usario + Funcionando + Cancelando TBR + Poniendo TBR (%d%% / %d min) + Emitiendo bolo (%.1f U) + Actualizando + Nunca + "Acción no disponible en la bomba " + Uso inseguro: bolo prolongado o multiwave activo. Modo Loop ha sido puesto a baja emision para solo 6 horas. Solo bolo normal se puede emitir en modo loop. + "Uso inseguro: la bomba usa base diferente a la primera. El loop ha sido apagado. Elige primero perfil en la bomba y acualiza. " + Un bolo de mismo valor ha sido dado durante el pasado minuto. Para evitar bolos dobles y asegurarse contra bugs esto no es permitido. + Ahora + Leiendo historia bomba + Alarmas + " Activando perfil base " + "Nivel del deposito bajo " + Bateria casi agotada + La bomba muesta el error E%d: %s + Para leer historial de los errores, pincha unos segundo el boton \"ALARMAS\" ATENCION: esto puede causar un bug. La bomba no vuelve a conectarse - necesitas pulsar un boton en la misma bomba para reiniciarse. Deberias evitar esto. + Para leer el hisorial TDD de la bomba pulsa el boton TDDS unso segundos. ATENCION: esto puede causar un bug. La bomba no vuelve a conectarse - necesitas pulsar un boton en la misma bomba para reiniciarse. Deberias evitar esto. + Mínimo: %3.1f U + Media: %3.1f U + Máximo: %3.1f U + Bajo + Vacio + Normal + Se necesita actualizar reloj de la bomba + Historial + Alerta + "Esto lee todo el historial y estado de la bomba, tus datos, la base. Bolos, basales temporales y tratamientos seran copiados y agregados si no existen ya. Esto puede causar duplicaciones, por que la hora de la bomba no es precisa. Es uso de esto con el loop normal solo deb ser usado en cirumstancisas especiales. Si de todas meneras quieres usar esto pulsa este boton unos segundos otra vez. ADVERTENCIA: esto puede causar un bug. La bomba no vuelve a conectarse - necesitas pulsar un boton en la misma bomba para reiniciarse. Deberias evitar esto. " + "Estas seguro, de que quieres leer todos los datos de la bomba y acceptar las consequencias de esta acción? " + TBR cancelada, advertencia acceptada + Emision del bolo fallado. Ningún bolo se ha emitido. Para asegurarse, por favor controle la bomba para evitar bolo doble. Para evitar bugs no se reinician bolos automaticamente. + "Solo %.2f U del bolo mandado de %.2f U ha sido emitido por causa de un error. Por favorn controla la bomba para confirmar y toma acciones apropiadas. " + "Fallo de emitir bolo y de controlar historical de la bomba.Por favor controla manualmente y crea un record en Careportal si el bolo ha sido emitido. " + Reestablecido coneccion fallada. + "No hay suficiente insulina en el deposito para emitir bolo. " + "Error al emitir bolo prolongado. " + bomba no alcanzable treshold [min] + TT + Versión no acceptada de Nightscout + Activar loop + Desactivar loop + Base: + Base temporal no emitida + Base temporal + Delta: + IOB: From 44e6c874c0e2bc78a9b65af9cf35d53970724ba9 Mon Sep 17 00:00:00 2001 From: Andrew Warrington Date: Mon, 29 Jan 2018 23:31:54 +0100 Subject: [PATCH 12/22] BaseWatchFace: Resolve issue causing Bolus and Wizard activities to fail to complete. --- .../info/nightscout/androidaps/watchfaces/BaseWatchFace.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java index ea5b41176b..4da66729e3 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java @@ -70,7 +70,6 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen public boolean layoutSet = false; public boolean bIsRound = false; public int pointSize = 2; - public int missed_readings_alert_id = 818; public BgGraphBuilder bgGraphBuilder; public LineChartView chart; public ArrayList bgDataList = new ArrayList<>(); @@ -181,7 +180,6 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen } } ); - ListenerService.requestData(this); wakeLock.acquire(50); } @@ -639,7 +637,7 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen chart.setViewportCalculationEnabled(true); chart.setMaximumViewport(chart.getMaximumViewport()); } else { - ListenerService.requestData(this); + //ListenerService.requestData(this); } } From 0f9273093a9a9947326193f10f9b0563c4c480fe Mon Sep 17 00:00:00 2001 From: Andrew Warrington Date: Mon, 29 Jan 2018 23:34:03 +0100 Subject: [PATCH 13/22] BaseWatchFace: Resolve issue causing Bolus and Wizard activities to fail to complete. --- .../info/nightscout/androidaps/watchfaces/BaseWatchFace.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java index 4da66729e3..fab81aafb9 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java @@ -636,8 +636,6 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen chart.setLineChartData(bgGraphBuilder.lineData()); chart.setViewportCalculationEnabled(true); chart.setMaximumViewport(chart.getMaximumViewport()); - } else { - //ListenerService.requestData(this); } } From 3a0d5d73f8215a86650bdb26ee83cce90c037db0 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Tue, 30 Jan 2018 01:02:21 +0100 Subject: [PATCH 14/22] filter null BT devices --- .../PumpDanaR/BluetoothDevicePreference.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/BluetoothDevicePreference.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/BluetoothDevicePreference.java index 63e14f0921..e39fdcfdaa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/BluetoothDevicePreference.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/BluetoothDevicePreference.java @@ -6,6 +6,7 @@ import android.preference.ListPreference; import android.util.AttributeSet; import java.util.Set; +import java.util.Vector; public class BluetoothDevicePreference extends ListPreference { @@ -13,25 +14,22 @@ public class BluetoothDevicePreference extends ListPreference { super(context, attrs); BluetoothAdapter bta = BluetoothAdapter.getDefaultAdapter(); - Integer size = 0; - if (bta != null) { - size += bta.getBondedDevices().size(); - } - CharSequence[] entries = new CharSequence[size]; - int i = 0; + Vector entries = new Vector(); if (bta != null) { Set pairedDevices = bta.getBondedDevices(); for (BluetoothDevice dev : pairedDevices) { - entries[i] = dev.getName(); - i++; + String name = dev.getName(); + if(name != null) { + entries.add(name); + } } } - setEntries(entries); - setEntryValues(entries); + setEntries(entries.toArray(new CharSequence[0])); + setEntryValues(entries.toArray(new CharSequence[0])); } public BluetoothDevicePreference(Context context) { this(context, null); } -} \ No newline at end of file +} From a6f65f5d338caf25d6d2c7d5fe424dfa86c9fc84 Mon Sep 17 00:00:00 2001 From: "Markus M. May" Date: Tue, 30 Jan 2018 19:52:57 +0100 Subject: [PATCH 15/22] Enhance insulin plugin test --- .../Insulin/InsulinOrefBasePluginTest.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePluginTest.java index de128175cc..83e9442364 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePluginTest.java @@ -47,11 +47,33 @@ public class InsulinOrefBasePluginTest extends InsulinOrefBasePlugin { assertEquals(expected, this.iobCalcForTreatment(treatment, 0, 0d)); this.peak = 30; + this.dia = 4; long time = System.currentTimeMillis(); + + // check directly after bolus + treatment.date = time; + treatment.insulin = 10d; + assertEquals(10d, this.iobCalcForTreatment(treatment, time).iobContrib, 0.1); + + // check after 1 hour treatment.date = time - 1 * 60 * 60 * 1000; // 1 hour treatment.insulin = 10d; - assertEquals(3.92, this.iobCalcForTreatment(treatment, time).iobContrib, 0.1); + + // check after 2 hour + treatment.date = time - 2 * 60 * 60 * 1000; // 1 hour + treatment.insulin = 10d; + assertEquals(0.77, this.iobCalcForTreatment(treatment, time).iobContrib, 0.1); + + // check after 3 hour + treatment.date = time - 3 * 60 * 60 * 1000; // 1 hour + treatment.insulin = 10d; + assertEquals(0.10, this.iobCalcForTreatment(treatment, time).iobContrib, 0.1); + + // check after dia + treatment.date = time - 4 * 60 * 60 * 1000; + treatment.insulin = 10d; + assertEquals(0d, this.iobCalcForTreatment(treatment, time).iobContrib, 0.1); } From 1ea324d87165905a6a9c5099533254a95d72dfc3 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 31 Jan 2018 14:42:36 +0100 Subject: [PATCH 16/22] Add issue template. --- ISSUE_TEMPLATE.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 ISSUE_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..db66ffec38 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,10 @@ +Reporting bugs +-------------- +- Note the precise time the problem occurred and describe the circumstances and steps that caused + the problem +- Note the Build version (found in the About dialog in the app, when pressing the three dots in the + upper-right corner). +- Obtain the app's log files, which can be found on the phone in + _/storage/emulated/0/Android/data/info.nightscout.androidaps/_ + See https://github.com/MilosKozak/AndroidAPS/wiki/Accessing-logfiles +- Open an issue at https://github.com/MilosKozak/AndroidAPS/issues/new \ No newline at end of file From 815247dabbdece0c8a375c6b4f7be2294ffbdea0 Mon Sep 17 00:00:00 2001 From: CaroGo Date: Wed, 31 Jan 2018 16:51:00 +0100 Subject: [PATCH 17/22] Update strings.xml I did a few changes... --- app/src/main/res/values-es/strings.xml | 80 +++++++++++++------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 71e911402b..0bdaeac441 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -39,7 +39,7 @@ Insulina [U] Carbohidratos [g] Glucosa - Hidratos Carbono + Carbohidratos Corrección U Bolo IOB @@ -53,7 +53,7 @@ Depósito: OK Error de SQL - Última ejecución + Última acción Parámetros de entrada Estado de glucosa Basal temporal actual @@ -61,7 +61,7 @@ Perfil Datos de comidas Resultado - No hay disponibles datos de glucosa + No hay datos disponibles de glucosa Sin perfil disponible No se dispone de bomba Ninguna acción requerida @@ -86,7 +86,7 @@ Bomba Tratamientos - Temp Basales + Basales temporales Perfil APS General @@ -128,11 +128,11 @@ Lazo cerrado Lazo abierto Nueva propuesta disponible - Versión de NSClient no soportada + Versión de NSClient no apoyada NSClient no instalado. Registro perdido! BG disponible en NS Estado de la bomba disponible en NS - Aceptados + Acceptado manualmente LAZO DESACTIVADO POR RESTRICCIONES Czech English @@ -144,7 +144,7 @@ NOTA Pregunta Ejercicio - Cambio Lugar Bomba + Cambio Lugar Cánula Insertar sensor Iniciar sensor Cambio Cartucho insulina @@ -155,14 +155,14 @@ Combo bolo Basal Temporal Inicio Basal Temporal Fin - Hidratos Carbono Corrección + Corrección Carbohidratos OpenAPS Offline Tipo de evento Otro Medidor Sensor - Hidratos Carbono + Carbohidratos Insulina Tiempo absorción Dividir @@ -207,7 +207,7 @@ Acuerdo de licencia de usuario final No deben utilizarse para tomar decisiones médicas. NO HAY GARANTÍA PARA EL PROGRAMA, la extensión permitida por la legislación aplicable. Excepto cuando se indique de otra forma por escrito, los tenedores del copyright y / u otras partes proporcionan el programa \"tal cual\" sin garantía de ningún tipo, ya sea expresa o implícita, incluyendo, pero no limitado a, las garantías implícitas de COMERCIALIZACIÓN E IDONEIDAD PARA UN FIN DETERMINADO . TODO EL RIESGO EN CUANTO A LA CALIDAD Y RENDIMIENTO DEL PROGRAMA ES CON USTED. SI EL PROGRAMA TIENE UN ERROR, asume el coste de cualquier servicio, reparación o corrección. Entiendo y acepto - Salvar + Guardar No se encuentra adaptador Bluetooth El dispositivo seleccionado no se encuentra Error de conexión de la bomba @@ -216,7 +216,7 @@ Unidades diarias Último bolo: h antes - Datos invalidos + Datos inválidos Valor no establecido correctamente Recargar Perfil Ver perfil @@ -275,8 +275,8 @@ Oclusión Detener Parar pulsado - Esperando bomba. Click to refresh. - Va a entregar% .2fU + Esperando bomba. Pulsar para actualizar. + Se entregará % .2fU Configuración de visualización y monitoreo, y el análisis de los basales y ratios Comprobar que los datos de BG están disponibles en Nightscout, y que los datos de la bomba de insulina se están subiendo Empezar con bucle abierto @@ -295,26 +295,26 @@ Korean Acciones Corr - Loop Inactivo + Lazo Inactivo Bolo Comida Valor %s fuera de limites Botón Texto: - Carbs: + Carbohidratos: Validar: Añadir Editar Eliminar Asistente Ajustes asistente - Loop se ha desactivado - Loop se ha activado - Loop inactivo - loop activo + Lazo se ha desactivado + Lazo se ha activado + Lazo inactivo + Lazo activo Basal temporal cancelada Fallo cancelación basal temporal Fallo inicio basal temporal Basal temporal %.2fU/h para %d min iniciada correctamente - Permitir comandos SMS remotos + Permitir ordenes SMS remotas Para parar basal temporal responder con codigo %s AndroidAPS iniciado Español @@ -327,26 +327,26 @@ Comando desconocido o respuesta incorrecta ¡Por favor asegurar que la cantidad coincide con la especificación del set de infusión! Para iniciar basal %.2fU/h responder con código %s - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " + "ACC" + "REL" + "BombaV" + "Trat" + "ObjTempAmpl" + "ObjTemp" + "SMS" + "PerfSipmple" + "Perf" + "General" + "Obj" + "Oaps" + "Lazo" + "PerfLoc" + "Dana" + "Conf" + "CPP" + "CP" Actividad - Por favo reinicia el teléfono o AndroidAPS desde ajustes de sistema, sino AndroidAPS no guardara registros (importantes para trazar y verificar que el algoritmo funciona correctamente) + Por favor reinicia el teléfono o AndroidAPS desde ajustes de sistema, sino AndroidAPS no guardará registros (importantes para trazar y verificar que el algoritmo funcione correctamente) Matriz de %d elementos. Valor actual: Ratio Basal: Valor basal menor del mínimo. Perfil no fijado. @@ -357,7 +357,7 @@ Inhabilitar EasyUI modo en bomba Habilitar bolos extendidos en bomba Cambio de modo de U/d a U/h en bomba - Comida temprano + Comer pronto Marca ALTA Iniciando . . . Perfil Local From 2157022735dfa45e966af81660442c52f845ea29 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 31 Jan 2018 23:21:02 +0100 Subject: [PATCH 18/22] bump 1.58 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 5cd4c9af95..2f22df9728 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -57,7 +57,7 @@ android { targetSdkVersion 23 multiDexEnabled true versionCode 1500 - version "1.57a-dev" + version "1.58" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", generateGitBuild() From 0139047432e75a31e74821e9b44a48ab8ad7eae5 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Thu, 1 Feb 2018 07:36:33 +0100 Subject: [PATCH 19/22] Revert "Update strings.xml" --- app/src/main/res/values-es/strings.xml | 80 +++++++++++++------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 0bdaeac441..71e911402b 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -39,7 +39,7 @@ Insulina [U] Carbohidratos [g] Glucosa - Carbohidratos + Hidratos Carbono Corrección U Bolo IOB @@ -53,7 +53,7 @@ Depósito: OK Error de SQL - Última acción + Última ejecución Parámetros de entrada Estado de glucosa Basal temporal actual @@ -61,7 +61,7 @@ Perfil Datos de comidas Resultado - No hay datos disponibles de glucosa + No hay disponibles datos de glucosa Sin perfil disponible No se dispone de bomba Ninguna acción requerida @@ -86,7 +86,7 @@ Bomba Tratamientos - Basales temporales + Temp Basales Perfil APS General @@ -128,11 +128,11 @@ Lazo cerrado Lazo abierto Nueva propuesta disponible - Versión de NSClient no apoyada + Versión de NSClient no soportada NSClient no instalado. Registro perdido! BG disponible en NS Estado de la bomba disponible en NS - Acceptado manualmente + Aceptados LAZO DESACTIVADO POR RESTRICCIONES Czech English @@ -144,7 +144,7 @@ NOTA Pregunta Ejercicio - Cambio Lugar Cánula + Cambio Lugar Bomba Insertar sensor Iniciar sensor Cambio Cartucho insulina @@ -155,14 +155,14 @@ Combo bolo Basal Temporal Inicio Basal Temporal Fin - Corrección Carbohidratos + Hidratos Carbono Corrección OpenAPS Offline Tipo de evento Otro Medidor Sensor - Carbohidratos + Hidratos Carbono Insulina Tiempo absorción Dividir @@ -207,7 +207,7 @@ Acuerdo de licencia de usuario final No deben utilizarse para tomar decisiones médicas. NO HAY GARANTÍA PARA EL PROGRAMA, la extensión permitida por la legislación aplicable. Excepto cuando se indique de otra forma por escrito, los tenedores del copyright y / u otras partes proporcionan el programa \"tal cual\" sin garantía de ningún tipo, ya sea expresa o implícita, incluyendo, pero no limitado a, las garantías implícitas de COMERCIALIZACIÓN E IDONEIDAD PARA UN FIN DETERMINADO . TODO EL RIESGO EN CUANTO A LA CALIDAD Y RENDIMIENTO DEL PROGRAMA ES CON USTED. SI EL PROGRAMA TIENE UN ERROR, asume el coste de cualquier servicio, reparación o corrección. Entiendo y acepto - Guardar + Salvar No se encuentra adaptador Bluetooth El dispositivo seleccionado no se encuentra Error de conexión de la bomba @@ -216,7 +216,7 @@ Unidades diarias Último bolo: h antes - Datos inválidos + Datos invalidos Valor no establecido correctamente Recargar Perfil Ver perfil @@ -275,8 +275,8 @@ Oclusión Detener Parar pulsado - Esperando bomba. Pulsar para actualizar. - Se entregará % .2fU + Esperando bomba. Click to refresh. + Va a entregar% .2fU Configuración de visualización y monitoreo, y el análisis de los basales y ratios Comprobar que los datos de BG están disponibles en Nightscout, y que los datos de la bomba de insulina se están subiendo Empezar con bucle abierto @@ -295,26 +295,26 @@ Korean Acciones Corr - Lazo Inactivo + Loop Inactivo Bolo Comida Valor %s fuera de limites Botón Texto: - Carbohidratos: + Carbs: Validar: Añadir Editar Eliminar Asistente Ajustes asistente - Lazo se ha desactivado - Lazo se ha activado - Lazo inactivo - Lazo activo + Loop se ha desactivado + Loop se ha activado + Loop inactivo + loop activo Basal temporal cancelada Fallo cancelación basal temporal Fallo inicio basal temporal Basal temporal %.2fU/h para %d min iniciada correctamente - Permitir ordenes SMS remotas + Permitir comandos SMS remotos Para parar basal temporal responder con codigo %s AndroidAPS iniciado Español @@ -327,26 +327,26 @@ Comando desconocido o respuesta incorrecta ¡Por favor asegurar que la cantidad coincide con la especificación del set de infusión! Para iniciar basal %.2fU/h responder con código %s - "ACC" - "REL" - "BombaV" - "Trat" - "ObjTempAmpl" - "ObjTemp" - "SMS" - "PerfSipmple" - "Perf" - "General" - "Obj" - "Oaps" - "Lazo" - "PerfLoc" - "Dana" - "Conf" - "CPP" - "CP" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " Actividad - Por favor reinicia el teléfono o AndroidAPS desde ajustes de sistema, sino AndroidAPS no guardará registros (importantes para trazar y verificar que el algoritmo funcione correctamente) + Por favo reinicia el teléfono o AndroidAPS desde ajustes de sistema, sino AndroidAPS no guardara registros (importantes para trazar y verificar que el algoritmo funciona correctamente) Matriz de %d elementos. Valor actual: Ratio Basal: Valor basal menor del mínimo. Perfil no fijado. @@ -357,7 +357,7 @@ Inhabilitar EasyUI modo en bomba Habilitar bolos extendidos en bomba Cambio de modo de U/d a U/h en bomba - Comer pronto + Comida temprano Marca ALTA Iniciando . . . Perfil Local From f49f3c7e4b37f54ea086e509847ef5f9f39efb46 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Fri, 2 Feb 2018 22:23:28 +0100 Subject: [PATCH 20/22] Clean up string resources. (cherry picked from commit 4adcffc) --- app/src/main/res/values-de/strings.xml | 4 ++-- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values/strings.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 8d41ca768c..a0e32e76de 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -726,7 +726,7 @@ Bitte starte dein Telefon neu oder starte AndroidAPS in den System-Einstellungen neu. Andernfalls wird AndroidAPS nicht protokolliert (wichtig zum Nachverfolgen und Verifizieren, dass der Algorithmus korrekt funktioniert) TBR %.1f %s (%s) - Ein gleich großer Bolus wurde in der letzten Minute angefordert. Dies ist nicht zulässig, um ungewollte Doppelboli zu verhindern und vor eventuellen Bugs zu schützen. + Ein gleich großer Bolus wurde in den letzten zwei Minuten angefordert. Dies ist nicht zulässig, um ungewollte Doppelboli zu verhindern und vor eventuellen Bugs zu schützen. Historie wird gelesen Basalratenprofil wird aktualisiert Verbindung wird wieder hergestellt @@ -753,7 +753,7 @@ Die Pumpe zeigt einen Fehler an E%d: %s Unsichere Verwendung: In der Pumpe ist nicht das erste Basalratenprofil gewählt. Der Loop wird deaktiviert bis dies korrigiert ist. Unsichere Verwendung: Ein erweiterter oder Multiwave-Bolus ist aktiv. Der Loop wird für die nächsten 6 Stunden kein zusätzliches Insulin abgeben. - Um die Fehlerhistorie der Pumpe zu lesen, drücke lange auf ALARME.\nWARNUNG: Es gibt einen bekannten Fehler in der Pumpe, der dazu führt, dass die Pumpe nach dieser Aktion erst wieder Verbindungen annimmt, wenn auf der Pumpe selbst eine Taste gedrückt wird. Aus diesem Grund sollte diese Aktion nicht durchgeführt werden. + Um die Fehlerhistorie der Pumpe zu lesen, drücke lange auf ALARME. Bitte aktualisiere die Uhrzeit der Pumpe Um die TDD-Statistik der Pumpe zu lesen, drücken Sie den TDDS Knopf lange.\nWARNUNG: Es gibt einen bekannten Fehler in der Pumpe der dazu führt, dass die Pumpe nach dieser Aktion erst wieder Verbindungen annimmt, wenn auf der Pumpe selbst ein Konpf gedrückt wird. Aus diesem Grund sollte diese Aktion nicht durchgeführt werden. Dies wird den gesamten Speicher und den Status der Pumpe auslesen sowie alle Einträge in „Meine Daten“ und die Basalrate. Boli und TBR werden unter Behandlungen gespeichert, sofern sie nicht bereits vorhanden sind. Dies kann zu doppelten Einträgen führen, wenn die Uhrzeit der Pumpe abweicht. Das Auslesen des Speichers ist normaler Weise für das Loopen unnötig und nur für besondere Umstände vorgesehen. Wenn Du es dennoch tun willst, drücke noch einmal länger den Button. ACHTUNG: Dies kann einen Fehler auslösen, der dazu führt, dass die Pumpe keine Verbindungsversuche mehr akzeptiert. Erst die Betätigung einer Taste an der Pumpe beendet diesen Zustand. Nach Möglichkeit sollte daher das Auslesen vermieden werden. diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 40f477e0c6..1503c4ef05 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -771,7 +771,7 @@ Instellen van basaal profiel Lezen van pomp historiek Ben je zeker dat je alle data van de pomp wil ophalen en de consequenties hiervan wil dragen? - Om de pomp fouthistoriek op te halen, druk lang op de Storingen knop OPGELET: dit kan een bug veroorzaken waardoor de pomp alle verbindingen verbreekt en het vereist is op een knop op de pomp te duwen, dit wordt daarom afgeraden. + Om de pomp fouthistoriek op te halen, druk lang op de Storingen knop. Maar %.2f E van de gevraagde %.2f E zijn toegediend door een storing. Gelieve op de pomp te controleren en het gepaste gevolg uit te voeren. "Om de TTD van de pomp op te halen, lang duwen op de TDDS knop OPGELET: dit kan een bug veroorzaken waardoor de pomp alle verbindingen verbreekt en het vereist is op een knop op de pomp te duwen, dit wordt daarom afgeraden." Toedienen en controleren van de bolus in de pomp historiek is mislukt, controleer de pomp en creëer een manuele bolus in het Careportal tabblad diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f6d2245060..f297e92588 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -858,7 +858,7 @@ This will read the full history and state of the pump. Everything in \"My Data\" and the basal rate. Boluses and TBRs will be added to Treatments if they don\'t already exist. This can cause entries to be duplicated because the pump\'s time is imprecise. Using this when normally looping with the pump is highly discouraged and reserved for special circumstances. If you still want to do this, long press this button again.\n\nWARNING: this can trigger a bug which causes the pump to reject all connection attempts and requires pressing a button on the pump to recover and should therefore be avoided. Are you really sure you want to read all pump data and take the consequences of this action? TBR CANCELLED warning was confirmed - The pump could\'nt be reached. No bolus was given + The pump could not be reached. No bolus was given Bolus delivery failed. It appears no bolus was delivered. To be sure, please check the pump to avoid a double bolus and then bolus again. To guard against bugs, boluses are not automatically retried. Only %.2f U of the requested bolus of %.2f U was delivered due to an error. Please check the pump to verify this and take appropriate actions. Delivering the bolus and verifying the pump\'s history failed, please check the pump and manually create a bolus record using the Careportal tab if a bolus was delivered. @@ -867,7 +867,7 @@ Extended bolus delivery error %.2f U/h Reading basal profile - The pump history has changed after the bolus calculation was performed. The bolus was not delivered. Please recalculate if a bolus is still needed. If the same bolus amount is required, please wait a minute since boluses with the same amount are blocked when requested with less than tow minutes between them for safety (regardless of whether they were administered or not). + The pump history has changed after the bolus calculation was performed. The bolus was not delivered. Please recalculate if a bolus is still needed. If the same bolus amount is required, please wait two minutes since boluses with the same amount are blocked when requested with less than two minutes between them for safety (regardless of whether they were administered or not). Bolus successfully delivered, but adding the treatment entry failed. This can happen if two small boluses of the same size are administered within the last two minutes. Please check the pump history and treatment entries and use the Careportal to add missing entries. Make sure not to add any entries for the exact same minute and same amount. Rejecting high temp since calculation didn\'t consider recently changed pump history Refreshing pump state From 6c9effd027c850542fdd9529960fec6067bb59a2 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Fri, 2 Feb 2018 23:59:05 +0100 Subject: [PATCH 21/22] Minor cleanup to reduce merge noise. (cherry picked from commit 4015f73) --- .../info/nightscout/androidaps/data/DetailedBolusInfo.java | 2 +- .../java/info/nightscout/androidaps/data/PumpEnactResult.java | 2 +- .../info/nightscout/androidaps/interfaces/PumpInterface.java | 4 +--- .../androidaps/plugins/Overview/OverviewFragment.java | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java b/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java index 07dd1c9ed3..35d91f616e 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java +++ b/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java @@ -13,7 +13,7 @@ import info.nightscout.androidaps.db.Source; * Created by mike on 29.05.2017. */ -public class DetailedBolusInfo implements Cloneable { +public class DetailedBolusInfo { public long date = System.currentTimeMillis(); public String eventType = CareportalEvent.MEALBOLUS; public double insulin = 0; diff --git a/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java b/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java index 4300341018..d48aa318dc 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java +++ b/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java @@ -13,7 +13,7 @@ import info.nightscout.androidaps.R; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.Round; -public class PumpEnactResult extends Object { +public class PumpEnactResult { private static Logger log = LoggerFactory.getLogger(PumpEnactResult.class); public boolean success = false; // request was processed successfully (but possible no change was needed) diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java index a85a7f3421..4358e884ae 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java @@ -1,14 +1,12 @@ package info.nightscout.androidaps.interfaces; -import android.support.annotation.NonNull; - import org.json.JSONObject; import java.util.Date; import info.nightscout.androidaps.data.DetailedBolusInfo; -import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.data.PumpEnactResult; /** * Created by mike on 04.06.2016. diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java index 9b44af6477..0e96fee394 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java @@ -52,7 +52,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; From 435c4dee85006751c5619263c3ce2b42d1fd64a4 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Sat, 3 Feb 2018 12:29:43 +0100 Subject: [PATCH 22/22] Create Answer events when adding bolus to DB fails. (cherry picked from commit 947ea4f) --- .../androidaps/plugins/PumpCombo/ComboPlugin.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java index dc8ea4ca57..b3f2c9e570 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java @@ -4,6 +4,9 @@ import android.os.SystemClock; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import com.crashlytics.android.answers.Answers; +import com.crashlytics.android.answers.CustomEvent; + import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -610,6 +613,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.sResources.getString(R.string.combo_error_updating_treatment_record), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); } + Answers.getInstance().logCustom(new CustomEvent("ComboBolusToDbError") + .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) + .putCustomAttribute("version", BuildConfig.VERSION) + .putCustomAttribute("issue", "record with same timestamp existed and was overridden")); return false; } } catch (Exception e) { @@ -617,6 +624,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf if (dbi.isSMB) { Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.sResources.getString(R.string.combo_error_updating_treatment_record), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); + Answers.getInstance().logCustom(new CustomEvent("ComboBolusToDbError") + .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) + .putCustomAttribute("version", BuildConfig.VERSION) + .putCustomAttribute("issue", "adding record caused exception")); } return false; }