From c7e1338d660deaedfc729616b53d535edad9e3db Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 26 Dec 2019 18:52:09 +0100 Subject: [PATCH 01/56] Leaked certificate update --- app/src/main/assets/revoked_certs.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/assets/revoked_certs.txt b/app/src/main/assets/revoked_certs.txt index 59a55d9e42..41177d5667 100644 --- a/app/src/main/assets/revoked_certs.txt +++ b/app/src/main/assets/revoked_certs.txt @@ -1,2 +1,4 @@ #Demo certificate -51:6D:12:67:4C:27:F4:9B:9F:E5:42:9B:01:B3:98:E4:66:2B:85:B7:A8:DD:70:32:B7:6A:D7:97:9A:0D:97:10 \ No newline at end of file +51:6D:12:67:4C:27:F4:9B:9F:E5:42:9B:01:B3:98:E4:66:2B:85:B7:A8:DD:70:32:B7:6A:D7:97:9A:0D:97:10 +#Leaked +55:5D:70:C9:BE:10:41:7E:4B:01:A9:C4:C6:44:4A:F8:69:71:35:25:ED:95:23:16:C7:15:E8:EB:C6:08:FC:B1 From a4fa64efe2053be873daeda80b4a5a573f9461bd Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 27 Jan 2020 23:07:48 +0100 Subject: [PATCH 02/56] more logging --- .../nightscout/androidaps/db/DbRequest.java | 56 ++++++------------- .../plugins/general/nsclient/NSUpload.java | 4 +- .../plugins/general/nsclient/UploadQueue.java | 12 +--- 3 files changed, 20 insertions(+), 52 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/db/DbRequest.java b/app/src/main/java/info/nightscout/androidaps/db/DbRequest.java index bec190a353..6cd0491907 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DbRequest.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DbRequest.java @@ -41,79 +41,55 @@ public class DbRequest { } // dbAdd - public DbRequest(String action, String collection, JSONObject data) { + public DbRequest(String action, String collection, JSONObject json) { this.action = action; this.collection = collection; this.nsClientID = "" + DateUtil.now(); try { - data.put("NSCLIENT_ID", nsClientID); + json.put("NSCLIENT_ID", nsClientID); } catch (JSONException e) { e.printStackTrace(); } - this.data = data.toString(); + this.data = json.toString(); this._id = ""; } // dbUpdate, dbUpdateUnset - public DbRequest(String action, String collection, String _id, JSONObject data) { + public DbRequest(String action, String collection, String _id, JSONObject json) { this.action = action; this.collection = collection; this.nsClientID = "" + DateUtil.now(); try { - data.put("NSCLIENT_ID", nsClientID); + json.put("NSCLIENT_ID", nsClientID); } catch (JSONException e) { e.printStackTrace(); } - this.data = data.toString(); + this.data = json.toString(); this._id = _id; } // dbRemove public DbRequest(String action, String collection, String _id) { - JSONObject data = new JSONObject(); + JSONObject json = new JSONObject(); this.action = action; this.collection = collection; this.nsClientID = "" + DateUtil.now(); try { - data.put("NSCLIENT_ID", nsClientID); + json.put("NSCLIENT_ID", nsClientID); } catch (JSONException e) { e.printStackTrace(); } - this.data = data.toString(); + this.data = json.toString(); this._id = _id; } - public JSONObject toJSON() { - JSONObject object = new JSONObject(); - try { - object.put("action", action); - object.put("collection", collection); - object.put("data", new JSONObject(data)); - if (_id != null) object.put("_id", _id); - if (nsClientID != null) object.put("nsClientID", nsClientID); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return object; - } - - public static DbRequest fromJSON(JSONObject jsonObject) { - DbRequest result = new DbRequest(); - try { - if (jsonObject.has("action")) - result.action = jsonObject.getString("action"); - if (jsonObject.has("collection")) - result.collection = jsonObject.getString("collection"); - if (jsonObject.has("data")) - result.data = jsonObject.getJSONObject("data").toString(); - if (jsonObject.has("_id")) - result._id = jsonObject.getString("_id"); - if (jsonObject.has("nsClientID")) - result.nsClientID = jsonObject.getString("nsClientID"); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return result; + public String log() { + return + "\nnsClientID:" + nsClientID + + "\naction:" + action + + "\ncollection:" + collection + + "\ndata:" + data + + "\n_id:" + _id; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java index b735a153fb..7fd6694481 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java @@ -323,7 +323,9 @@ public class NSUpload { prebolus.put("created_at", DateUtil.toISOString(preBolusDate)); uploadCareportalEntryToNS(prebolus); } - UploadQueue.add(new DbRequest("dbAdd", "treatments", data)); + DbRequest dbr = new DbRequest("dbAdd", "treatments", data); + log.debug("Prepared: " + dbr.log()); + UploadQueue.add(dbr); } catch (Exception e) { log.error("Unhandled exception", e); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/UploadQueue.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/UploadQueue.java index f513f12756..aa5759fc22 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/UploadQueue.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/UploadQueue.java @@ -43,27 +43,17 @@ public class UploadQueue { public static void add(final DbRequest dbr) { startService(); - if (NSClientService.handler != null) { - NSClientService.handler.post(() -> { if (L.isEnabled(L.NSCLIENT)) - log.debug("Adding to queue: " + dbr.data); + log.debug("Adding to queue: " + dbr.log()); try { MainApp.getDbHelper().create(dbr); } catch (Exception e) { log.error("Unhandled exception", e); - dbr.nsClientID += "1"; - try { - MainApp.getDbHelper().create(dbr); - } catch (Exception e1) { - log.error("Unhandled exception", e1); - } } NSClientPlugin plugin = NSClientPlugin.getPlugin(); if (plugin != null) { plugin.resend("newdata"); } - }); - } } public static void clearQueue() { From 6b26ef2e88069652669184c48ef3def152facc1d Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 1 Feb 2020 22:44:23 +0100 Subject: [PATCH 03/56] prevent NPE --- .../pump/danaR/activities/DanaRHistoryActivity.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRHistoryActivity.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRHistoryActivity.kt index 361f8e716e..d63ab0eb14 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRHistoryActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRHistoryActivity.kt @@ -100,23 +100,23 @@ class DanaRHistoryActivity : NoSplashAppCompatActivity() { danar_history_reload.setOnClickListener { val selected = danar_history_spinner.selectedItem as TypeList runOnUiThread { - danar_history_reload.visibility = View.GONE - danar_history_status.visibility = View.VISIBLE + danar_history_reload?.visibility = View.GONE + danar_history_status?.visibility = View.VISIBLE } clearCardView() ConfigBuilderPlugin.getPlugin().commandQueue.loadHistory(selected.type, object : Callback() { override fun run() { loadDataFromDB(selected.type) runOnUiThread { - danar_history_reload.visibility = View.VISIBLE - danar_history_status.visibility = View.GONE + danar_history_reload?.visibility = View.VISIBLE + danar_history_status?.visibility = View.GONE } } }) } danar_history_spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) { - val selected = danar_history_spinner.selectedItem as TypeList + val selected = danar_history_spinner?.selectedItem as TypeList? ?: return loadDataFromDB(selected.type) showingType = selected.type } From 4b07adb2a8bbe21d4bdc2c390e67d9ded050a962 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 1 Feb 2020 23:46:23 +0100 Subject: [PATCH 04/56] Restore ns_noupload function. Thanks to @twain47 --- .../plugins/general/nsclient/UploadQueue.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/UploadQueue.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/UploadQueue.java index aa5759fc22..f87cee7900 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/UploadQueue.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/UploadQueue.java @@ -14,10 +14,12 @@ import org.slf4j.LoggerFactory; import java.sql.SQLException; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.DbRequest; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService; +import info.nightscout.androidaps.utils.SP; /** * Created by mike on 21.02.2016. @@ -42,21 +44,22 @@ public class UploadQueue { } public static void add(final DbRequest dbr) { + if (SP.getBoolean(R.string.key_ns_noupload, false)) return; startService(); - if (L.isEnabled(L.NSCLIENT)) - log.debug("Adding to queue: " + dbr.log()); - try { - MainApp.getDbHelper().create(dbr); - } catch (Exception e) { - log.error("Unhandled exception", e); - } - NSClientPlugin plugin = NSClientPlugin.getPlugin(); - if (plugin != null) { - plugin.resend("newdata"); - } + if (L.isEnabled(L.NSCLIENT)) + log.debug("Adding to queue: " + dbr.log()); + try { + MainApp.getDbHelper().create(dbr); + } catch (Exception e) { + log.error("Unhandled exception", e); + } + NSClientPlugin plugin = NSClientPlugin.getPlugin(); + if (plugin != null) { + plugin.resend("newdata"); + } } - public static void clearQueue() { + static void clearQueue() { startService(); if (NSClientService.handler != null) { NSClientService.handler.post(() -> { @@ -104,7 +107,7 @@ public class UploadQueue { } } - public String textList() { + String textList() { String result = ""; CloseableIterator iterator; try { From 8bcf901e6fc6815698aeefb7be3361600bbd8a04 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 1 Feb 2020 23:47:12 +0100 Subject: [PATCH 05/56] New Crowdin translations (#2405) * New translations strings.xml (Russian) * New translations strings.xml (Korean) * New translations strings.xml (Korean) * New translations strings.xml (Korean) * New translations strings.xml (Korean) * New translations strings.xml (Korean) * New translations objectives.xml (Korean) * New translations exam.xml (Korean) * New translations exam.xml (Korean) * New translations strings.xml (Korean) * New translations strings.xml (Bulgarian) * New translations strings.xml (Korean) * New translations exam.xml (Korean) * New translations strings.xml (Korean) --- app/src/main/res/values-bg-rBG/strings.xml | 3 + app/src/main/res/values-ko-rKR/exam.xml | 168 +++++++++++++++++- app/src/main/res/values-ko-rKR/objectives.xml | 64 ++++++- app/src/main/res/values-ko-rKR/strings.xml | 153 +++++++++++++++- app/src/main/res/values-ru-rRU/strings.xml | 2 + wear/src/main/res/values-ko-rKR/strings.xml | 109 +++++++++++- 6 files changed, 489 insertions(+), 10 deletions(-) diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index e5e933fa3e..d3a01e2d86 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -1446,4 +1446,7 @@ Използване на удължен болус ще спре режим затворен цикъл за времето на болуса. Сигурни ли сте? Затворен цикъл е недостъпен поради стартиран Удължен болус УБ + \"PhoneChecker\" + Меню на графиката + АS diff --git a/app/src/main/res/values-ko-rKR/exam.xml b/app/src/main/res/values-ko-rKR/exam.xml index 70489fbc5e..2b76f2c396 100644 --- a/app/src/main/res/values-ko-rKR/exam.xml +++ b/app/src/main/res/values-ko-rKR/exam.xml @@ -1,3 +1,169 @@ - + + DIA에 대하여 올바른 것은? + 주제: Duration of Insulin Action(DIA) + 최소값은 3시간입니다. + 최소값은 5시간입니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Configuration/Config-Builder.html?#insulin + 당신이 사용중인 펌프의 DIA값과 동일합니다. + 당신이 값을 결정해야합니다(최소 5시간 이상) + 주제: 저혈당 임시 목표 + 저혈당 임시 목표를 설정하는 주된 이유가 무엇입니까? + 임시 Basal이 0일 경우 저혈당을 방지하기 위해서. + 저혈당때문에 섭취한 탄수화물로 인해 급격하게 혈당이 올라간 후 AAPS가 인슐린을 너무 많이 주입하는 것을 방지하기 위해서. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Usage/temptarget.html + 어떤 프로파일이 오프라인에서 설정할 수 있습니까? + 주제: 오프라인 프로파일 + NS 프로파일이 사용될 수 있지만, 오프라인 상에서 설정할 수는 없습니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Configuration/Config-Builder.html#profile + 주제: 펌프 일시중지하기 + 펌프 일시중지할땐 무엇을 해야합니까? + 인슐린이 주입되지 않을것이라는 것을 AAPS가 인지하도록 \'펌프 일시중지\'를 누릅니다. + 펌프가 일시중지되는 동안 \'Loop 일시중지\'를 눌러서 Loop를 중지합니다. + AAPS에선 아무 작업도 하지 않고, 그냥 펌프와 연결을 해제합니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Getting-Started/FAQ.html#other-settings + 주제: AndroidAPS 설정 + 다음중 당신의 AAPS 설정을 백업하기 위한 좋은 사례는 무엇입니까? + 정비 메뉴에서 설정 저장하기 합니다. + 저장된 설정파일을 이메일, 드롭박스, 구글드라이브 등에 저장한다… + AAPS 설치 후 바로 설정을 저장합니다. + 설정을 변경한 이후 바로 설정을 저장합니다. + 목표수행을 완료한 후 설정을 저장합니다. + 초기 설정이 완료되면 설정을 저장합니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Usage/ExportImportSettings.html + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Getting-Started/FAQ.html#what-emergency-equipment-is-recommended-to-take-with-me + 주제: CGM의 혈당 노이즈가 심할 때 + CGM 혈당의 노이즈가 심하다면 어떻게 해야합니까? + 아무것도 하지 않고, AAPS가 알아서 하게 내버려둔다. + 과도한 주입을 방지하기 위해 Loop를 중지한다. + CGM 센서를 교체한다. + 폰을 끈다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Usage/Smoothing-Blood-Glucose-Data-in-xDrip.html#smoothing-blood-glucose-data + CGM앱의 혈당 평활화 기능 작동 여부를 확인한다. + 주제: 운동 + 운동시 어떻게 하는 것이 도움이 됩니까? + 임시 목표 기능 사용. + 100%이하로 프로파일을 변경합니다. + 100%이상으로 프로파일을 변경합니다. + Loop를 중지합니다. + 운동 시작전 운동 임시목표를 설정합니다. + 운동 시작 후 운동 임시목표를 설정하는 것은 운동 시작 전에 설정하는 것보다 나쁜 결과를 초래합니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Usage/temptarget.html#activity-temp-target + 주제: Loop 중지/일시중지 + Loop가 중지/일시중지 되었을때 인슐린이 주입됩니까? + 네, Basal 인슐린은 계속 주입됩니다. + 아니오, 인슐린 주입이 모두 중지됩니다. + 주제: Basal, ISF, and IC 테스트 + Basal, ISF 그리고 IC 값은 언제 확인해야 합니까? + Loop를 시작하기 전. + 저혈당 빈도가 많을 때 + 고혈당 빈도가 많을 때 + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Getting-Started/FAQ.html#androidaps-settings + 주제: 사전 요구사항 + 필요한 것이 무엇입니까? + 유효한 프로파일 정보 (Basal, IC, ISF, DIA). + APK파일을 빌드하기 위한 컴퓨터. + 지원되는 폰. + 자동차. + 목표수행하기 위해 필요한 Nightscout. + Tidepool 계정. + 구글(Google) 계정. + 깃허브(Github) 계정. + 안드로이드 개발 경험. + 미니메드(MiniMed) 670G 펌프. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Module/module.html + 스마트워치. + 지원되는 연속혈당측정기(CGM). + 주제: AndroidAPS 업데이트 + 올바른 것을 선택하세요. + Git이 설치되어 있어야 합니다. + 신버전이 나온 후 시간이 되면 바로 업데이트 하세요. + 동일한 signing keys를 사용하여야 합니다. + 시스템이 잘 작동한다면 절대 업데이트하지마세요. + 지인에게 신버전의 APK를 달라고 요청합니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Installing-AndroidAPS/Update-to-new-version.html#update-to-a-new-version-or-branch + 주제: 문제해결 + 어디에 도움을 요청해야 합니까? + AndroidAPS 페이스북 그룹에 가입합니다. + AndroidAPS documentation을 읽어봅니다. + AndroidAPS Gitter Room을 방문합니다. + AndroidAPS Google support에 방문합니다. + 내분비과 의사와 상담해봅니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Installing-AndroidAPS/Update-to-new-version.html#troubleshooting + https://www.facebook.com/groups/AndroidAPSUsers/ + https://gitter.im/MilosKozak/AndroidAPS + 주제: 인슐린 플러그인 + \'초-초속효성 Oref\' 플러그인과 사용해야할 인슐린은 무엇입니까? + 피아스프(Fiasp®) + 노보래피드(NovoRapid®) + 휴마로그(Humalog®) + 액트라피드(Actrapid®) + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Configuration/Config-Builder.html#insulin + 주제: 민감도 플러그인 + 어떤 민감도 알고리즘에 구성 가능한 시간 범위가 있습니까? + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Configuration/Sensitivity-detection-and-COB.html + UAM기능(알려지지않은 탄수화물 인식 기능)을 사용하기 위해서 어떤 민감도 알고리즘을 사용해야합니까? + 주제: 탄수화물 입력 에러 + 부적절한 탄수화물을 입력하였다면 어떻게 하여야 합니까? + 관리에서, 부적절한 탄수화물 입력을 삭제하고, 새 탄수화물을 입력합니다. + 채움 기능을 이용하여 거짓으로 인슐린을 추가합니다. + 주제: 지방과 단백질 음식 + 많은 양의 지방 그리고\/또는 단백질이 있는 음식을 섭취할땐 어떻게 합니까? + 지방과 단백질을 탄수화물로 계산하고 \"확장 탄수화물\"기능을 사용합니다. + 지방과 단백질을 탄수화물로 계산하고 Bolus 계산에 추가합니다. + 지방과 단백질을 보완하기 위해서 확장 Bouls를 사용합니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Usage/Extended-Carbs.html + 주제: 원격 모니터링 + 당신의 아이의 AAPS를 어떻게 원격으로 모니터합니까? + Nightscout 사이트를 이용합니다. + 덱스콤 정식앱을 사용한다면 덱스콤 팔로우앱을 사용합니다(혈당만). + xDrip앱을 사용한다면 덱스콤 팔로우앱을 사용합니다. + xDrip에서 팔로어 모드를 이용합니다. + 아이폰에서 Loop앱을 이용합니다. + 아이폰에서 Spike앱을 이용합니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Children/Children.html + 주제: ISF(인슐린 민감도) + 높은 ISF 값은 AAPS가 고혈당을 잡으려고 할때 보다 적은 인슐린 주입을 하게끔 합니다. + 낮은 ISF 값은 AAPS가 고혈당을 잡으려고 할때 보다 적은 인슐린 주입을 하게끔 합니다. + ISF 값 변경은 AAPS가 고혈당을 잡으려고 할때의 인슐린양에 아무런 영향을 주지 않습니다. + 설정에서 ISF 값을 입력해야합니다. + 변경사항을 적용하는데 프로파일에서 ISF 값 변경하는 것으로 충분합니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Getting-Started/FAQ.html#insulin-sensitivity-factor-isf-mmol-l-u-or-mg-dl-u + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Usage/Profiles.html + Topic: IC(인슐린 대 탄수화물) 비율 + 높은 IC 비율은 탄수화물 섭취시 인슐린이 보다 덜 주입되게 합니다. + 낮은 IC 비율은 탄수화물 섭취시 인슐린이 보다 덜 주입되게 합니다. + COB가 0 인 경우 IC 비율을 변경하면 혈당을 교정하기 위해 다른 양의 인슐린이 주입됩니다. + Bread Unit을 10g 혹은 12g으로 계산한다면 IC 값도 달라집니다. + IC의 의미는 다음과 같습니다: 1U의 인슐린에 대한 적정 Bread Unit 양 + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Getting-Started/FAQ.html#carbohydrate-to-insulin-ratio-cr-g-u + 주제: 프로파일 변경 + 프로파일을 90%로 설정하면 어떻게 됩니까? + Basal이 10% 높아집니다. + Basal이 10% 낮아집니다. + IC 값이 10% 높아집니다. + IC 값이 10% 낮아집니다. + ISF 값이 10% 높아집니다. + ISF 값이 10% 낮아집니다. + 전체적으로 약 10 % 더 적은 인슐린이 주입되게 됩니다. + 목표가 10% 높아집니다. + 목표가 10% 낮아집니다. + 하한 목표만 10% 낮아집니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Usage/Profiles.html?highlight=profile%20switch#profile-switch + 평소보다 1 시간 일찍 일어난 경우, AAPS에게 당신의 변경된 일정을 알리려면 어떻게 해야합니까? + 시간이동 1로 프로파일을 변경합니다. + 시간이동 -1로 프로파일을 변경합니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Usage/Profiles.html?highlight=profile%20switch#timeshift + 시간이동 60으로 프로파일을 변경합니다. + 시간이동 -60으로 프로파일을 변경합니다. + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Module/module.html#good-individual-dosage-algorithm-for-your-diabetes-therapy + Topic: Basal 값에 대한 도움 + Basal값 등과 관련된 도움을 어디서 받아야 하나요? + 의료진 + 구글(Google) + 페이스북(Facebook) + 기타 의약품 + AAPS는 혈당을 올리기 위하여 Basal값을 내립니다. SGLT2 억제제(gliflozins) 계열의 의약품들은 예상되는 혈당 상승을 억제하여 인슐린 결핍 (케톤산증)을 유발할 수 있습니다. +\n일반적인 브랜드명은 다음과 같습니다: Invokana®, Forxiga®, Jardiance®, Steglatro®, Suglat®, Apleway®, Deberza®, Synjardy®, Vokanamet®, Xigduo®.\n\n본인은 AAPS를 사용할 때 이러한 의약품을 복용하지 않거나 혹은 이러한 의약품을 복용하기 전에 Loop를 비활성화 할것임을 약속합니다. + diff --git a/app/src/main/res/values-ko-rKR/objectives.xml b/app/src/main/res/values-ko-rKR/objectives.xml index 70489fbc5e..4bc1ebbb35 100644 --- a/app/src/main/res/values-ko-rKR/objectives.xml +++ b/app/src/main/res/values-ko-rKR/objectives.xml @@ -1,3 +1,65 @@ - + + 뒤로 + 시작 + 확인 + %1$d. 목표 + 목표 %1$d이 시작되지 않았습니다 + 목표 %1$d이 완료되지 않았습니다 + 시각화 및 모니터링 설정하고, Basal과 비율을 분석합니다. + Nightscout에서 혈당 데이터가 잘 들어오는지, 펌프, 인슐린 데이터가 업로드 되는지 확인합니다 + Open Loop를 시작합니다 + 며칠 동안 Open Loop 모드를 사용하고 수동으로 임시Basal을 실행하여 봅니다. 사용자 정의 임시 목표와 (\'활동\', \'저혈당\' 같은) 기본 임시목표를 사용해봅니다 + 임시Basal 추천기능과 Open Loop에 대해 이해합니다 + 이 경험을 토대로, 최대 Basal을 결정하고 이를 펌프와 설정에 입력합니다 + Closed Loop를 시작하고 저혈당인슐린 중지 기능(LGS)을 사용해 봅니다 + 최대 IOB = 0 인 상태로 Closed Loop를 몇일동안 실행하되 저혈당 인슐린일시중지(LGS)가 많이 발생하지 않도록 합니다 + Closed Loop를 조정하여 최대 IOB를 0 이상으로 올려서 서서히 혈당 목표치를 낮추어 봅니다 + 혈당을 낮추기 전에 몇일간 사용해보되 최소한 하루는 저혈당 알람이 발생하지 않도록 해봅니다 + 필요하면 Basal과 비율을 조절하고, auto-sens를 활성화합니다 + 섭취한 탄수화물양을 입력하고 1주일동안 낮시간대에 loop를 성공적으로 사용하여 봅니다 + AMA(Advanced Meal Assist)같은 낮시간대를 위한 추가적인 기능들을 실행하여 봅니다 + 낮시간대에 SMB(Super Micro Bolus)같은 추가기능을 활성화해 사용해봅니다 + SMB가 잘 작동하게 하기위해서 wiki를 반드시 읽은 다음 maxIOB 값을 올려보세요! maxIOB=평균 식사 Bolus + 3 x 최대하루 Basal이면 적당한 시작값입니다 + NS에서 혈당이 확인 가능합니다 + NS에서 펌프상태가 확인 가능합니다 + 수동 주입 + 완료: %1$s + AndroidAPS를 사용하는 방법을 배워봅니다 + AndroidAPS에서 다양한 작업을 수행해보세요 + 10분동안 프로파일 90%를 설정해보세요(개요에서 프로파일명을 길게 눌러보세요) + 샤워한다고 가정하고 펌프를 1시간 동안 펌프를 일시중지하세요 (개요에서 Open Loop를 길게 눌러보세요) + ... 그리고 같은 방법으로 펌프를 재연결하세요 + 10분의 사용자정의 임시 목표를 생성해 보세요 (개요에서 본인의 현재 목표혈당을 길게 눌러보세요) + 구성관리자에서 실행 플러그인을 활성화하고 메뉴에서 표시되게 합니다 + Loop 플러그인 내용을 표시합니다 + 개요의 혈당 차트를 길게 눌러 차트 시간을 변경하세요 + 입력 + 당신이 OpenAPS 사용자였고 당신의 NS가 최소 3개월의 Loop 데이터가 저장되어 있다면, objectives@androidaps.org로 메일을 보내 당신의 NS주소를 알려주시고 목표를 건너뛸 수 있는 코드를 요청하세요. 그리고 개발자로 부터 받은 코드를 입력하세요. + 코드 인증 + 잘못된 코드 + 당신의 지식을 확인해봅니다 + 다음 질문에 대해 공부하고 올바른 답을 선택하세요 + 다음 시간까지 답변 불가능: %1$s + 잘못된 답변! + 다음 미답변 + 요청 코드: %1$s + (올바른 답변을 모두 체크하세요) + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Getting-Started/FAQ.html#what-to-do-when-taking-a-shower-or-bath + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Getting-Started/Screenshots.html#the-homescreen + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Getting-Started/Screenshots.html#config-builder + https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Getting-Started/Screenshots.html#the-homescreen + 인터넷에 연결되지 않음 + 시간을 가져오지 못했습니다 + 목표 요구 사항이 충족되지 않음 + + %1$d 일 + + + %1$d 시간 + + + %1$d 분 + + diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 167b2d0412..e4ecfc6ed9 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -96,6 +96,7 @@ 프로파일 식사 데이터 결과 + 결과: %1$s %2$s 혈당 데이터 없음 변경사항 없음 요청 @@ -108,7 +109,7 @@ 구성 관리자 목표 OpenAPS MA - 개요 + NS 프로파일 Simple 프로파일 관리 @@ -123,7 +124,7 @@ APS 어떤 APS 알고리즘을 사용합니까? 일반 - 유용한 여러가지 플로그인 + 유용한 여러가지 플러그인 어떤 제약을 적용합니까? 제한 @@ -142,6 +143,7 @@ 제한 위반 Bolus 주입 에러 임시Basal 주입 에러 + Basal 값 [%] 새 임시Basal 적용: 관리 계산기 @@ -179,6 +181,7 @@ CGM 센서 삽입 CGM 센서 시작 인슐린 카트리지 교체 + 프로파일 변경 간식Bolus 식사Bolus 교정Bolus @@ -199,6 +202,7 @@ 퍼센트 절대값 노트 + 이벤트 시간 프로파일 입력자 혈당 종류 @@ -206,6 +210,7 @@ 임시Basal 확장 Bolus Nightscout 버전: + 누락 %1$dg 설정이 저장되었습니다 다음 위치에 설정을 저장하시겠습니까 다음 위치에서 설정을 불러오시겠습니까 @@ -222,6 +227,7 @@ 연결중 연결됨 연결 끊김 + 다나 펌프 설정 최종 사용자 라이선스 동의서 이 프로그램을 의학적 결정을 내리는 데 사용해서는 안되며, 여기에 대한 어떠한 보증도 없습니다. 이 프로그램의 품질과 성능에 관한 모든 위험은 사용자에게 있습니다.\nMUST NOT BE USED TO MAKE MEDICAL DECISIONS. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 모두 이해하였고 동의합니다. @@ -248,16 +254,30 @@ 허가된 전화번호 +XXXXXXXXXX;+YYYYYYYYYY Bolus %1$.2fU 을 주입하려면 %2$s 를 입력하고 답장하세요 + 식사Bolus %1$.2f을 주입하려면 %2$s를 입력하고 답장하세요 + 임시목표 %1$s를 설정하려면 %2$s를 입력하고 답장하세요 + 임시목표를 취소하려면 %1$s를 입력하고 답장하세요 + SMS 원격 기능을 비활성화려면 %1$s를 입력하고 답장하세요.\n\nAAPS 마스터폰을 통해서만 다시 활성화할 수 있습니다. + SMS 원격 기능이 중지되었습니다. 다시 활성화하려면 AAPS 마스터폰을 이용하세요. 보정값 %1$.2f을 전송하려면 %2$s 를 입력하고 답장하세요 Bolus failed + 원격 Bolus를 주입한 후 얼마간의 시간이 흐른 후에야 다음 원격 Bolus주입이 가능합니다 + 원격 Bolus를 주입한 후 몇분이 지나야 다음 원격 Bolus 주입이 가능하게 합니까 + 안전을 위하여 이 설정을 수정하기 위해 최소 2개의 폰 번호를 추가해야합니다. Bolus %1$.2fU이 주입 완료되었습니다. %1$.2fU을 주입합니다 Bolus %1$.2fU이 주입 완료되었습니다 + 식사Bolus %1$.2f이 주입 완료되었습니다 + %2$d 분 동안 목표 %1$s + %2$d 분 동안 목표 %1$s 설정이 완료되었습니다 + 임시 목표 취소가 완료되었습니다 %1$.2fU 주입중 SMS 원격 명령 사용하기 체혈 센서 수동 + 임시 목표 + 임시 목표 취소 DanaR 프로파일 설정 인슐린활동시간(DIA) [h] 인슐린 활동 기간 @@ -310,10 +330,13 @@ %2$d분 동안 Basal %1$.2fU/h 주입하려면 %3$s 를 입력하고 답장하세요 프로파일을 %1$s %2$d%%로 변경하려면 %3$s 를 입력하고 답장하세요 %2$d분 동안 확장 Bolus %1$.2fU 주입하려면 %3$s 를 입력하고 답장하세요 + %2$s에 %1$dg을 입력하려면 %3$s를 입력하고 답장하세요 %2$d 분 동안 Basal %1$d%% 주입하려면 %3$s을 입력하고 답장하세요 %1$d분동안 Loop 일시중지하려면 %2$s 를 입력하고 답장하세요 Temp Basal %1$.2fU/h for %2$d min started successfully %2$d분 동안 확장Bolus %1$.2fU주입이 성공적으로 시작되었습니다 + 탄수화물 %1$dg 입력이 완료되었습니다 + 탄수화물 %1$dg 입력이 실패하였습니다 %2$d분 동안 임시Basal %1$d%%주입이 성공적으로 시작되었습니다 Temp Basal start failed 확장 Bolus 실행 실패 @@ -347,11 +370,14 @@ 버튼1 버튼2 버튼3 + 단위: + 단위 mg/dl mmol/l + DIA 목표 범위: 차트 표시 범위 - 스마트워치 차트 고/저혈당 선 + 홈화면/스마트워치의 차트에서 표시되는 고/저혈당 선 저혈당 선 고혈당 선 워치 @@ -390,6 +416,7 @@ 식사직전 저혈당 활동 + 기록 삭제 DanaR 통계 누적 일총량 지수가중 일총량 @@ -527,8 +554,12 @@ 마법사에서 Superbolus 활성화하기 마법사에서 Superbolus 기능을 활성화합니다. 어떤 기능인지 확실히 알기전까지 활성화 하지 마세요. 제대로 알지 못하고 사용하면 일슐린이 과다 주입될 수 있습니다! 홈화면에 상태 표시등 보여주기 + 홈화면에 확장 상태등 표시하기 + 홈화면에 캐뉼라 사용기간(cage), 인슐린 사용기간(iage), 센서 사용기간(sage), 펌프용 주사기(reservoir)와 배터리(battery) 남은 양에 대한 확장 표시등을 활성화합니다. 주사기량 경고 기준값[U] 주사기량 위험 기준값[U] + 배터리 잔량 경고값 [%] + 배터리 잔량 위험값 [%] IOB COB 펌웨어 @@ -552,6 +583,7 @@ 인슐린 사용기간 시간 프로파일이 유효하지 않습니다!!! + 프로파일 변경 실행 펌프배터리사용기간 펌프 배터리 교체 알람 옵션 @@ -561,8 +593,8 @@ 위험 저혈당 누락 데이터 위험 누락 데이터 - 누락 데이터 기준값[분] - 위험 누락 데이터 기준값[분] + 누락 데이터 기준값 [min] + 위험 누락 데이터 기준값 [min] autosens 시간 [h] 민감도를 감지하기 위해 계산될 총 시간 (탄수화물 흡수 시간은 제외됩니다.) 펌프 @@ -594,6 +626,7 @@ 취소 모든 프로파일이 로드되지 않았습니다. 값이 저장되지 않았습니다! + 다른 앱 (예 : xDrip)으로 데이터 전송을 활성화합니다. AAPS 또는 NSClient 인스턴스를 두 개 이상 설치 한 경우 활성화하지 마세요! Local Broadcasts 활성화하기 활동 & 피드백 탄수화물 & Bolus @@ -618,6 +651,7 @@ 펌프연동 대기중 연동완료 연동시간초과 + 동기화 현재까지 발견된 기기가 없습니다. 빈 주사기 혈당측정알람 @@ -652,6 +686,7 @@ g 시간 + ]]> kJ En @@ -680,6 +715,7 @@ 혈당 업로드 설정 델타(혈당증분값) 자세히 보여주기 소수점 자리 추가된 증분값 보여주기 + SMB 최대 분 SMB가 Basal을 제한할 수 있는 최대 시간(분) 지원되지 않는 펌프 펌웨어 혈당 데이터를 xDrip+에 전송하기 @@ -726,6 +762,7 @@ 2개의 동일한 양의 Bolus 주입이 요청되었습니다. 이중으로 Bolus가 주입 되는 사고를 막고 버그로부터 보호하기 위하여 이는 금지됩니다. 현재 펌프 이력 읽기 + 펌프 이력 Basal 프로파일 설정 펌프 카트리지 레벨이 낮습니다. 펌프배터리가 부족합니다. @@ -745,6 +782,7 @@ Sight %1$.2f 시간 + %1$d 분 항상 SMB를 사용합니다. Bolus와 독립적으로 항상 SMB를 사용합니다. G5처럼 잘 필터된 혈당소스와만 사용이 가능합니다. 탄수화물 이후 SMB를 사용합니다. @@ -851,7 +889,7 @@ 펌프 중지 펌프 시작 펌프 일시중지 - 식사 최대 흡수 시간[h] + 식사 최대 흡수 시간 [h] 식사가 모두 흡수되었다고 간주되는 시간. 나머지 탄수화물은 모두 없어집니다. 시간 관리창에 노트 영역 보여주기 @@ -921,7 +959,11 @@ 소리 진동 모두 + LCD 시간 [seconds] + 화면조명 시간 [seconds] 혈당 단위 + 종료 [hours] + 낮은 주사기량 [Units] 펌프로 옵션 저장 켜짐 꺼짐 @@ -1114,6 +1156,8 @@ 임시 Basal 업로드 프로파일변경, 임시목표 업로드 혈당 테스트 업로드 + 24시간 미만의 썸머타임 변경 + 썸머타임 변경이 3시간 미만입니다 - Closed Loop 비활성됨 내부 저장 용량 제한 내부 저장 공간을 최소 %1$d MB 이상 비우세요! Loop가 비활성화되었습니다! 잘못된 형식 @@ -1137,6 +1181,7 @@ 유효하지 않은 버전을 이용 중입니다. Loop가 비활성화 되었습니다! 오래된 버전 아주 오래된 버전 + 최소 %1$d일 새버전이 가능합니다! %2$d일 후엔 LGS(저혈당주입중지)으로 복귀되며, %3$d일이후엔 Loop가 비활성화 될 것입니다 2h %1$.2fU Dexcom 앱(패치버전) @@ -1164,12 +1209,20 @@ 경도 거리 [m]: 이름: - 마지막 Bolus 전 + %1$s %2$s + + 당신이 그 지역내에 있을 때 + 당신이 그 지역밖에 있을 때 + 당신이 다음 이름의 지역에 들어갔을 때 + 당신이 다음 이름의 지역에서 떠날 때 + 마지막 Bolus 마지막 Bolus 시간 %1$s %2$s 분 전 COB COB %1$s %2$.0f 작업명 편집 + 실행 유형을 선택하세요 + 트리거 유형을 선택하세요 트리거: 삭제 전제 조건: @@ -1197,6 +1250,8 @@ 선택되지 않음(심플뷰) 알카라인(확장뷰) 리튬(확장뷰) + NiZn (확장 뷰) + Bolus/관리 디버깅 스캔 중지 @@ -1235,6 +1290,7 @@ 시작되지 않았습니다. RileyLink 초기화… RileyLink 에러 + RileyLink 와 펌프 튜닝 펌프 연결 문제 연결됨 @@ -1259,6 +1315,7 @@ 지원되지 않는 펌프 주파수입니다. RileyLink 주소가 유효하지 않습니다. 감지된 펌프타입이 설정된 타입과 다릅니다. + Basal 프로파일/패턴 설정이 펌프에서 활성화되지 않았습니다. 펌프에서 활성화해주세요. 펌프에 설정된 Basal 프로파일이 올바르지 않습니다 (STD 이어야 합니다). 펌프에 잘못된 TBR 유형이 설정되었습니다 (절대값이어야합니다). 펌프에 잘못된 최대 Bolus가 설정되었습니다 (%1$.2f 이어야 합니다.). @@ -1303,6 +1360,15 @@ 임시 Basal 받기 임시 Basal 설정 Bolus 설정 + 프로파일을 변경 + 프로파일을 %1$s으로 변경 + 펌프와의 마지막 연결 + 펌프와의 마지막 연결 [분 전] + 펌프와의 마지막 연결 %1$s %2$s 분 전 + SMS 전송: %1$s + 모든 번호에 SMS 전송 + 문자 포함된 SMS 보내기 + %2$+.2fU]]> Bolus 제약 적용: %2$.2fU 에서 %3$.2fU]]> !!!!! 느린 탄수화물 흡수 감지: %2$d%% of time. 계산을 다시 확인하십시오. COB를 과대하게 측정하여 더 많은 인슐린이 주입될 수 있습니다 !!!!!]]> %1$.0f / %2$d U @@ -1310,4 +1376,77 @@ Bolus 마법사는 계산을 수행하지만 계산된 인슐린의 이 부분만 주입됩니다. SMB 알고리즘에 유용합니다. 불러오는 중… 스누즈 + 시간 범위 + 시간은 %1$s 와 %2$s사이입니다 + 사이 + 닫기 + 설정이 프로파일에서의 최대 Basal보다 낮은 이유로 최대 Basal을 올립니다 + 잘못된 메시지 내용 + %1$s ISF: %2$.1f + %1$.0fg IC: %2$.1f + %1$.1fg IC: %2$.1f + %1$d%% + Bolus 마법사 + + 프로파일명: + 선택: + 단위 + 프로파일을 변경하고 현재 프로파일에 대한 변경 사항을 버리시겠습니까? + %1$dg + 켜기 + 끄기 + 완료 초기화 + 시작 초기화 + 시간 감지 + 목표를 초기화하시겠습니까? 진행상황이 삭제됩니다. + 펌프가 선택되지 않음 + 사용하시는 혈당 단위를 선택하세요 + 로컬 프로파일 변경을 NS에 업로드하기 + DIA + IC + ISF + TARG + 복사 + 우선 현재 변경사항을을 저장하거나 재설정하세요 + 현재 프로파일을 삭제 하시겠습니까? + 이 프로파일 변경을 기반으로 새 로컬 프로파일을 만드시겠습니까? + 프로파일명에 점을 포함하고 있습니다.\n이는 NS에서 지원하지 않습니다.\n프로파일이 NS에 업로드되지 않습니다. + 혈당 정상범위의 하한값(표시 전용) + 혈당 정상범위의 상한값(표시 전용) + 정렬 + 나이: + 몸무게: + ID: + 확인 + 가장 많이 사용된 프로파일: + 참고: 이 화면에 보이는 데이터만 익명으로 업로드됩니다. ID는 AndroidAPS 설치에 할당됩니다. 기본 프로파일이 변경되면 데이터를 다시 제출할 수 있지만 어느정도 시간 범위의 결과가 보이도록 최소 1주일 이상 실행하여 주세요. 당신의 도움 감사하겠습니다. + 조사 + 유효하지 않은 나이입니다 + 유효하지 않은 몸무게입니다 + %1$s: ∑: %2$.2f Bol: %3$.2f Bas: %4$.2f]]> + %1$s: Low: %2$02d%% In: %3$02d%% High: %4$02d%%]]> + 평균 + TDD + TIR + 활동 모니터 + 활동 통계를 초기화하시겠습니까? + 통계 + 무작위 혈당 + 무작위로 혈당을 생성합니다(데모 버전 전용) + BG + 도구 + 계산 표시 + 에러 + 12h + 24h + 자동화 이벤트 + 이미 설정됨 + 메시지 + 대기열을 삭제하시겠습니까? 대기열에 있는 모든 데이터가 삭제됩니다! + 확장 Bolus 기능을 사용하는 동안에는 Closed Loop 모드가 중지됩니다. 정말 원하십니까? + 확장 Bolus 사용으로 인해 Closed Loop가 비활성화됨 + EB + \"전화확인\" + 차트 메뉴 + AS diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 78b3450504..c717182dc4 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -1449,4 +1449,6 @@ Context | Edit Context Замкнутый цикл отключен из-за работы Пролонгированного Болюса ПБ \"PhoneChecker\" + Меню графика + Авточувств diff --git a/wear/src/main/res/values-ko-rKR/strings.xml b/wear/src/main/res/values-ko-rKR/strings.xml index 70489fbc5e..cc4e5e62be 100644 --- a/wear/src/main/res/values-ko-rKR/strings.xml +++ b/wear/src/main/res/values-ko-rKR/strings.xml @@ -1,3 +1,110 @@ - + + AAPS + AAPS + AAPS + AAPS(대) + AAPS(큰차트) + AAPS(차트없음) + AAPS(원형) + AAPSv2 + AAPS(조종석) + AAPS(스팀펑크) + 데이터없음! + 오래된 데이터! + %1$s 이후 + AAPS와 연결! + %1$s 이후 받은 데이터가 없습니다! 폰에서 AAPS가 워치로 데이터를 보냈는지 확인하세요 + AAPS 데이터가 %1$s 오래되었습니다! 센서, xDrip+, NS, AAPS 설정 또는 기타사항을 확인하세요! + 켜기 + 끄기 + Bolus 주입시 진동 + 단위 + 날짜 표시 + IOB 표시 + COB 표시 + 증분 표시 + 평균증분 표시 + 폰배터리 표시 + 종합 배터리 표시 + Basal 값 표시 + Loog 상태 표시 + 혈당 표시 + 화살표 표시 + \'분전\' 표시 + 어두움 + Basal 강조 + 경계선 색상매칭 + 차트 기간 + 1시간 + 2시간 + 3시간 + 4시간 + 5시간 + 입력 형태 + 기본 + 오른손잡이 + 왼손잡이 + 모던스타일 + 증분 밀도(스팀펑크) + + + + 자동 + 큰 숫자 + 원형 이력 + 연한 원형 이력 + 애니메이션 + 메뉴에서 마법사 + 메뉴에서 교체 + 단일 목표 + 마법사 퍼센트 + 컴플리케이션 탭 동작 + 컴플리케이션에서 유니코드 사용 + 버전: + 임시목표 + 마법사 + Bolus + 확장탄수화물 + 설정 + 상태 + 교체/채움 + 없음 + 기본 + 메뉴 + 기간 + 목표 + 하한값 + 상한값 + 탄수화물 + 퍼센트 + 시작 [min] + 기간 [h] + 인슐린 + 프리셋 1 + 프리셋 2 + 프리셋 3 + 양 제한없음 + 확인 + 상태 펌프 + 상태 LOOP + 시간이동 + TDD 가중 + Bolus + 펌프 + Loop + CPP + TDD + Carb + IOB + 상태 없음 + mg/dl + mmol/l + g + U + U/h + h + d + w + From b5a64f4d859d579bd3d2f77f223945e366daf15f Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 2 Feb 2020 22:12:54 +0100 Subject: [PATCH 06/56] better timestamps on Loop tab --- .../plugins/aps/loop/LoopFragment.kt | 12 +- .../plugins/aps/loop/LoopPlugin.java | 30 ++- .../general/overview/OverviewFragment.java | 2 +- .../general/wear/ActionStringHandler.java | 4 +- .../wearintegration/WatchUpdaterService.java | 2 +- .../nightscout/androidaps/utils/DateUtil.java | 13 + app/src/main/res/layout/loop_fragment.xml | 225 ++++++++++++++---- app/src/main/res/values/strings.xml | 4 + 8 files changed, 231 insertions(+), 61 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt index e7dbacb891..5625fd978f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopFragment.kt @@ -77,8 +77,11 @@ class LoopFragment : Fragment() { loop_source?.text = it.source ?: "" loop_lastrun?.text = it.lastAPSRun?.let { lastRun -> DateUtil.dateAndTimeString(lastRun.time) } ?: "" - loop_lastenact?.text = it.lastAPSRun?.let { lastEnact -> DateUtil.dateAndTimeString(lastEnact.time) } - ?: "" + loop_smbrequest_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastSMBRequest) + loop_smbexecution_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastSMBEnact) + loop_tbrrequest_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastTBRRequest) + loop_tbrexecution_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastTBREnact) + loop_tbrsetbypump?.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml()) } ?: "" loop_smbsetbypump?.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml()) } @@ -102,7 +105,10 @@ class LoopFragment : Fragment() { loop_constraintsprocessed?.text = "" loop_source?.text = "" loop_lastrun?.text = "" - loop_lastenact?.text = "" + loop_smbrequest_time?.text = "" + loop_smbexecution_time?.text = "" + loop_tbrrequest_time?.text = "" + loop_tbrexecution_time?.text = "" loop_tbrsetbypump?.text = "" loop_smbsetbypump?.text = "" } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java index 7492dc64dd..b0d6f89065 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java @@ -57,6 +57,7 @@ import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.commands.Command; +import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.T; @@ -84,9 +85,9 @@ public class LoopPlugin extends PluginBase { return loopPlugin; } - private long loopSuspendedTill = 0L; // end of manual loop suspend - private boolean isSuperBolus = false; - private boolean isDisconnected = false; + private long loopSuspendedTill; // end of manual loop suspend + private boolean isSuperBolus; + private boolean isDisconnected; public class LastRun { public APSResult request = null; @@ -95,8 +96,11 @@ public class LoopPlugin extends PluginBase { public PumpEnactResult smbSetByPump = null; public String source = null; public Date lastAPSRun = null; - public Date lastEnact = null; - public Date lastOpenModeAccept; + public long lastTBREnact = 0; + public long lastSMBEnact = 0; + public long lastTBRRequest = 0; + public long lastSMBRequest = 0; + public long lastOpenModeAccept; } static public LastRun lastRun = null; @@ -342,6 +346,10 @@ public class LoopPlugin extends PluginBase { lastRun.source = ((PluginBase) usedAPS).getName(); lastRun.tbrSetByPump = null; lastRun.smbSetByPump = null; + lastRun.lastTBREnact = 0; + lastRun.lastTBRRequest = 0; + lastRun.lastSMBEnact = 0; + lastRun.lastSMBRequest = 0; NSUpload.uploadDeviceStatus(); @@ -378,14 +386,17 @@ public class LoopPlugin extends PluginBase { public void run() { if (result.enacted || result.success) { lastRun.tbrSetByPump = result; - lastRun.lastEnact = lastRun.lastAPSRun; + lastRun.lastTBRRequest = lastRun.lastAPSRun.getTime(); + lastRun.lastTBREnact = DateUtil.now(); + RxBus.INSTANCE.send(new EventLoopUpdateGui()); applySMBRequest(resultAfterConstraints, new Callback() { @Override public void run() { //Callback is only called if a bolus was acutally requested if (result.enacted || result.success) { lastRun.smbSetByPump = result; - lastRun.lastEnact = lastRun.lastAPSRun; + lastRun.lastSMBRequest = lastRun.lastAPSRun.getTime(); + lastRun.lastSMBEnact = DateUtil.now(); } else { new Thread(() -> { SystemClock.sleep(1000); @@ -465,8 +476,9 @@ public class LoopPlugin extends PluginBase { public void run() { if (result.enacted) { lastRun.tbrSetByPump = result; - lastRun.lastEnact = new Date(); - lastRun.lastOpenModeAccept = new Date(); + lastRun.lastTBRRequest = lastRun.lastAPSRun.getTime(); + lastRun.lastTBREnact = DateUtil.now(); + lastRun.lastOpenModeAccept = DateUtil.now(); NSUpload.uploadDeviceStatus(); SP.incInt(R.string.key_ObjectivesmanualEnacts); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java index dcce040759..be963d7a9a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java @@ -1113,7 +1113,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, if (acceptTempButton != null) { boolean showAcceptButton = !closedLoopEnabled.value(); // Open mode needed showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist - showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result + showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == 0 || finalLastRun.lastOpenModeAccept < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.isChangeRequested(); // change is requested if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java index cae9817a55..0fd820a4da 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java @@ -502,8 +502,8 @@ public class ActionStringHandler { if (LoopPlugin.lastRun.lastAPSRun != null) ret += "\nLast Run: " + DateUtil.timeString(LoopPlugin.lastRun.lastAPSRun); - if (LoopPlugin.lastRun.lastEnact != null) - ret += "\nLast Enact: " + DateUtil.timeString(LoopPlugin.lastRun.lastEnact); + if (LoopPlugin.lastRun.lastTBREnact != 0) + ret += "\nLast Enact: " + DateUtil.timeString(LoopPlugin.lastRun.lastTBREnact); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java index 39676f17b4..2293473338 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java @@ -735,7 +735,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog //OpenAPS status if (Config.APS) { //we are AndroidAPS - openApsStatus = LoopPlugin.lastRun != null && LoopPlugin.lastRun.lastEnact != null && LoopPlugin.lastRun.lastEnact.getTime() != 0 ? LoopPlugin.lastRun.lastEnact.getTime() : -1; + openApsStatus = LoopPlugin.lastRun != null && LoopPlugin.lastRun.lastTBREnact != 0 ? LoopPlugin.lastRun.lastTBREnact : -1; } else { //NSClient or remote openApsStatus = NSDeviceStatus.getOpenApsTimestamp(); diff --git a/app/src/main/java/info/nightscout/androidaps/utils/DateUtil.java b/app/src/main/java/info/nightscout/androidaps/utils/DateUtil.java index b03d8cb43f..aa228b96ca 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/DateUtil.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/DateUtil.java @@ -141,6 +141,14 @@ public class DateUtil { return new DateTime(mills).toString(DateTimeFormat.forPattern(format)); } + public static String timeStringWithSeconds(long mills) { + String format = "hh:mm:ssa"; + if (android.text.format.DateFormat.is24HourFormat(MainApp.instance())) { + format = "HH:mm:ss"; + } + return new DateTime(mills).toString(DateTimeFormat.forPattern(format)); + } + public static String timeFullString(long mills) { return new DateTime(mills).toString(DateTimeFormat.fullTime()); } @@ -158,6 +166,11 @@ public class DateUtil { return dateString(mills) + " " + timeString(mills); } + public static String dateAndTimeAndSecondsString(long mills) { + if (mills == 0) return ""; + return dateString(mills) + " " + timeStringWithSeconds(mills); + } + public static String dateAndTimeFullString(long mills) { return dateString(mills) + " " + timeFullString(mills); } diff --git a/app/src/main/res/layout/loop_fragment.xml b/app/src/main/res/layout/loop_fragment.xml index ef24280345..3b5066e533 100644 --- a/app/src/main/res/layout/loop_fragment.xml +++ b/app/src/main/res/layout/loop_fragment.xml @@ -57,51 +57,6 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \"PhoneChecker\" Chart menu AS + SMB request time + SMB execution time + Temp basal request time + Temp basal execution time From db47cd6fe9f52398380acdce94af9d0fde7570f4 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 3 Feb 2020 18:23:20 +0100 Subject: [PATCH 07/56] Android 10 permission --- .../nightscout/androidaps/MainActivity.java | 2 ++ .../overview/notifications/Notification.java | 1 + .../androidaps/utils/AndroidPermission.java | 19 +++++++++++++++++++ app/src/main/res/values/strings.xml | 1 + 4 files changed, 23 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index 8fa855cd7b..f74a58856f 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -147,6 +147,7 @@ public class MainActivity extends NoSplashAppCompatActivity { if (Config.PUMPDRIVERS) { AndroidPermission.notifyForLocationPermissions(this); AndroidPermission.notifyForSMSPermissions(this); + AndroidPermission.notifyForSystemWindowPermissions(this); } } @@ -245,6 +246,7 @@ public class MainActivity extends NoSplashAppCompatActivity { case AndroidPermission.CASE_SMS: case AndroidPermission.CASE_BATTERY: case AndroidPermission.CASE_PHONE_STATE: + case AndroidPermission.CASE_SYSTEM_WINDOW: break; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java index 28b0abd33d..dde005ba20 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java @@ -78,6 +78,7 @@ public class Notification { public static final int USERMESSAGE = 53; public static final int OVER_24H_TIME_CHANGE_REQUESTED = 54; public static final int INVALID_VERSION = 55; + public static final int PERMISSION_SYSTEM_WINDOW = 56; public int id; diff --git a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java b/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java index fdee5417a3..d884552ac4 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java @@ -32,6 +32,7 @@ public class AndroidPermission { public static final int CASE_LOCATION = 0x3; public static final int CASE_BATTERY = 0x4; public static final int CASE_PHONE_STATE = 0x5; + public static final int CASE_SYSTEM_WINDOW = 0x6; private static boolean permission_battery_optimization_failed = false; @@ -130,4 +131,22 @@ public class AndroidPermission { } else RxBus.INSTANCE.send(new EventDismissNotification(Notification.PERMISSION_LOCATION)); } + + public static synchronized void notifyForSystemWindowPermissions(Activity activity) { + if (!Settings.canDrawOverlays(activity)) { + NotificationWithAction notification = new NotificationWithAction(Notification.PERMISSION_SYSTEM_WINDOW, MainApp.gs(R.string.needsystemwindowpermission), Notification.URGENT); + notification.action(R.string.request, () -> { + // Check if Android Q or higher + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + // Show alert dialog to the user saying a separate permission is needed + // Launch the settings activity if the user prefers + Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + Uri.parse("package:" + activity.getPackageName())); + activity.startActivity(intent); + } + }); + RxBus.INSTANCE.send(new EventNewNotification(notification)); + } else + RxBus.INSTANCE.send(new EventDismissNotification(Notification.PERMISSION_SYSTEM_WINDOW)); + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 071021fa54..2e06c2a027 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1102,6 +1102,7 @@ Start your first objective Permission Ask for permission + Application needs system window permission for notifications Application needs location permission for BT scan Application needs storage permission to be able store log files Request From aaf66efa640d6ab1ea49f8667d455baab1364acd Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 3 Feb 2020 22:05:48 +0100 Subject: [PATCH 08/56] write offline events directly to DB --- .../plugins/aps/loop/LoopPlugin.java | 22 +++++++++++++++++-- .../automation/actions/ActionLoopResume.java | 2 +- .../plugins/general/nsclient/NSUpload.java | 8 +++---- .../general/overview/OverviewFragment.java | 6 ++--- .../smsCommunicator/SmsCommunicatorPlugin.kt | 4 ++-- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java index b0d6f89065..4710cf9b64 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java @@ -14,6 +14,8 @@ import android.os.SystemClock; import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; +import org.json.JSONException; +import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -697,7 +699,7 @@ public class LoopPlugin extends PluginBase { } }); } - NSUpload.uploadOpenAPSOffline(durationInMinutes); + createOfflineEvent(durationInMinutes); } public void suspendLoop(int durationInMinutes) { @@ -715,7 +717,23 @@ public class LoopPlugin extends PluginBase { } } }); - NSUpload.uploadOpenAPSOffline(durationInMinutes); + createOfflineEvent(durationInMinutes); } + public void createOfflineEvent(int durationInMinutes) { + JSONObject data = new JSONObject(); + try { + data.put("eventType", CareportalEvent.OPENAPSOFFLINE); + data.put("duration", durationInMinutes); + } catch (JSONException e) { + log.error("Unhandled exception", e); + } + CareportalEvent event = new CareportalEvent(); + event.date = DateUtil.now(); + event.source = Source.USER; + event.eventType = CareportalEvent.OPENAPSOFFLINE; + event.json = data.toString(); + MainApp.getDbHelper().createOrUpdate(event); + NSUpload.uploadOpenAPSOffline(event); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResume.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResume.java index 38e5dee33a..16b478bbc2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResume.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResume.java @@ -28,7 +28,7 @@ public class ActionLoopResume extends Action { if (LoopPlugin.getPlugin().isSuspended()) { LoopPlugin.getPlugin().suspendTo(0); ConfigBuilderPlugin.getPlugin().storeSettings("ActionLoopResume"); - NSUpload.uploadOpenAPSOffline(0); + LoopPlugin.getPlugin().createOfflineEvent(0); RxBus.INSTANCE.send(new EventRefreshOverview("ActionLoopResume")); if (callback != null) callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java index 7fd6694481..0bc15d1d45 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java @@ -336,12 +336,10 @@ public class NSUpload { UploadQueue.add(new DbRequest("dbRemove", "treatments", _id)); } - public static void uploadOpenAPSOffline(double durationInMinutes) { + public static void uploadOpenAPSOffline(CareportalEvent event) { try { - JSONObject data = new JSONObject(); - data.put("eventType", "OpenAPS Offline"); - data.put("duration", durationInMinutes); - data.put("created_at", DateUtil.toISOString(new Date())); + JSONObject data = new JSONObject(event.json); + data.put("created_at", DateUtil.toISOString(event.date)); data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name)); UploadQueue.add(new DbRequest("dbAdd", "treatments", data)); } catch (JSONException e) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java index be963d7a9a..931cca544b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java @@ -679,14 +679,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); - NSUpload.uploadOpenAPSOffline(24 * 60); // upload 24h, we don't know real duration + LoopPlugin.getPlugin().createOfflineEvent(24 * 60); // upload 24h, we don't know real duration return true; } else if (item.getTitle().equals(MainApp.gs(R.string.enableloop))) { loopPlugin.setPluginEnabled(PluginType.LOOP, true); loopPlugin.setFragmentVisible(PluginType.LOOP, true); ConfigBuilderPlugin.getPlugin().storeSettings("EnablingLoop"); updateGUI("suspendmenu"); - NSUpload.uploadOpenAPSOffline(0); + LoopPlugin.getPlugin().createOfflineEvent(0); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.resume)) || item.getTitle().equals(MainApp.gs(R.string.reconnect))) { @@ -701,7 +701,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } }); SP.putBoolean(R.string.key_objectiveusereconnect, true); - NSUpload.uploadOpenAPSOffline(0); + LoopPlugin.getPlugin().createOfflineEvent(0); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor1h))) { LoopPlugin.getPlugin().suspendLoop(60); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt index c180dffe83..0021574812 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt @@ -330,7 +330,7 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription() "RESUME" -> { LoopPlugin.getPlugin().suspendTo(0) send(EventRefreshOverview("SMS_LOOP_RESUME")) - NSUpload.uploadOpenAPSOffline(0.0) + LoopPlugin.getPlugin().createOfflineEvent(0) sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopresumed)) } "SUSPEND" -> { @@ -352,7 +352,7 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription() override fun run() { if (result.success) { LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + anInteger() * 60L * 1000) - NSUpload.uploadOpenAPSOffline(anInteger() * 60.toDouble()) + LoopPlugin.getPlugin().createOfflineEvent(anInteger() * 60) send(EventRefreshOverview("SMS_LOOP_SUSPENDED")) val replyText = MainApp.gs(R.string.smscommunicator_loopsuspended) + " " + MainApp.gs(if (result.success) R.string.smscommunicator_tempbasalcanceled else R.string.smscommunicator_tempbasalcancelfailed) From 850e79a068fbffa9f0c1fd885e528da9beba9f6c Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 3 Feb 2020 22:42:13 +0100 Subject: [PATCH 09/56] fix tests --- .../plugins/general/automation/actions/ActionLoopResumeTest.java | 1 + .../general/automation/actions/ActionLoopSuspendTest.java | 1 + 2 files changed, 2 insertions(+) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResumeTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResumeTest.java index c690681513..5e367942ea 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResumeTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResumeTest.java @@ -62,6 +62,7 @@ public class ActionLoopResumeTest { public void prepareTest() { AAPSMocker.mockMainApp(); AAPSMocker.mockApplicationContext(); + AAPSMocker.mockDatabaseHelper(); AAPSMocker.mockStrings(); AAPSMocker.mockSP(); AAPSMocker.mockConfigBuilder(); diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspendTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspendTest.java index 67e22b0d5b..142536681d 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspendTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspendTest.java @@ -79,6 +79,7 @@ public class ActionLoopSuspendTest { public void prepareTest() { AAPSMocker.mockMainApp(); AAPSMocker.mockApplicationContext(); + AAPSMocker.mockDatabaseHelper(); AAPSMocker.mockStrings(); AAPSMocker.mockSP(); AAPSMocker.mockConfigBuilder(); From a79393c65a7f0d9861e3ee66f7537cc2b598a931 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 4 Feb 2020 22:25:07 +0100 Subject: [PATCH 10/56] Log user actions --- .../androidaps/dialogs/CalibrationDialog.kt | 1 + .../androidaps/dialogs/CarbsDialog.kt | 5 +++++ .../nightscout/androidaps/dialogs/CareDialog.kt | 1 + .../dialogs/DialogFragmentWithDate.kt | 2 +- .../androidaps/dialogs/ErrorDialog.kt | 5 +++-- .../androidaps/dialogs/ExtendedBolusDialog.kt | 1 + .../nightscout/androidaps/dialogs/FillDialog.kt | 3 +++ .../androidaps/dialogs/InsulinDialog.kt | 3 +++ .../androidaps/dialogs/ProfileSwitchDialog.kt | 1 + .../androidaps/dialogs/TempBasalDialog.kt | 2 ++ .../androidaps/dialogs/TempTargetDialog.kt | 1 + .../androidaps/dialogs/TreatmentDialog.kt | 1 + .../plugins/general/actions/ActionsFragment.kt | 5 +++++ .../general/overview/OverviewFragment.java | 17 +++++++++++++++++ .../nightscout/androidaps/utils/BolusWizard.kt | 2 ++ 15 files changed, 47 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CalibrationDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CalibrationDialog.kt index 949e4e5fef..9503988dce 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CalibrationDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CalibrationDialog.kt @@ -56,6 +56,7 @@ class CalibrationDialog : DialogFragmentWithDate() { if (bg > 0) { activity?.let { activity -> OKDialog.showConfirmation(activity, MainApp.gs(R.string.overview_calibration), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), Runnable { + log.debug("USER ENTRY: CALIBRATION $bg") XdripCalibrations.confirmAndSendCalibration(bg, context) }) } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt index de457068c5..1f0c6643c1 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt @@ -177,6 +177,7 @@ class CarbsDialog : DialogFragmentWithDate() { activity?.let { activity -> OKDialog.showConfirmation(activity, MainApp.gs(R.string.carbs), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), Runnable { if (activitySelected) { + log.debug("USER ENTRY: TEMPTARGET ACTIVITY $activityTT duration: $activityTTDuration") val tempTarget = TempTarget() .date(eventTime) .duration(activityTTDuration) @@ -186,6 +187,7 @@ class CarbsDialog : DialogFragmentWithDate() { .high(Profile.toMgdl(activityTT, ProfileFunctions.getSystemUnits())) TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget) } else if (eatingSoonSelected) { + log.debug("USER ENTRY: TEMPTARGET EATING SOON $eatingSoonTT duration: $eatingSoonTTDuration") val tempTarget = TempTarget() .date(eventTime) .duration(eatingSoonTTDuration) @@ -195,6 +197,7 @@ class CarbsDialog : DialogFragmentWithDate() { .high(Profile.toMgdl(eatingSoonTT, ProfileFunctions.getSystemUnits())) TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget) } else if (hypoSelected) { + log.debug("USER ENTRY: TEMPTARGET HYPO $hypoTT duration: $hypoTTDuration") val tempTarget = TempTarget() .date(eventTime) .duration(hypoTTDuration) @@ -206,8 +209,10 @@ class CarbsDialog : DialogFragmentWithDate() { } if (carbsAfterConstraints > 0) { if (duration == 0) { + log.debug("USER ENTRY: CARBS $carbsAfterConstraints time: $time") CarbsGenerator.createCarb(carbsAfterConstraints, time, CareportalEvent.CARBCORRECTION, notes) } else { + log.debug("USER ENTRY: CARBS $carbsAfterConstraints time: $time duration: $duration") CarbsGenerator.generateCarbs(carbsAfterConstraints, time, duration, notes) NSUpload.uploadEvent(CareportalEvent.NOTE, time - 2000, MainApp.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset)) } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt index 0e47049cf1..da4a091b1d 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt @@ -180,6 +180,7 @@ class CareDialog : DialogFragmentWithDate() { EventType.EXERCISE -> CareportalEvent.EXERCISE } careportalEvent.json = json.toString() + log.debug("USER ENTRY: CAREPORTAL ${careportalEvent.eventType} json: ${careportalEvent.json}") MainApp.getDbHelper().createOrUpdate(careportalEvent) NSUpload.uploadCareportalEntryToNS(json) }, null) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/DialogFragmentWithDate.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/DialogFragmentWithDate.kt index da45e77990..ecaea0bc81 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/DialogFragmentWithDate.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/DialogFragmentWithDate.kt @@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory import java.util.* abstract class DialogFragmentWithDate : DialogFragment() { - private val log = LoggerFactory.getLogger(DialogFragmentWithDate::class.java) + val log = LoggerFactory.getLogger(DialogFragmentWithDate::class.java) var eventTime = DateUtil.now() var eventTimeChanged = false diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt index 538a2ca483..c084df7bf3 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt @@ -36,6 +36,7 @@ class ErrorDialog : DialogFragment() { bundle.getString("title")?.let { title = it } sound = bundle.getInt("sound", R.raw.error) } + log.debug("Error dialog displayed") return inflater.inflate(R.layout.dialog_error, container, false) } @@ -44,11 +45,11 @@ class ErrorDialog : DialogFragment() { error_title.text = title overview_error_ok.setOnClickListener { - log.debug("Error dialog ok button pressed") + log.debug("USER ENTRY: Error dialog ok button pressed") dismiss() } overview_error_mute.setOnClickListener { - log.debug("Error dialog mute button pressed") + log.debug("USER ENTRY: Error dialog mute button pressed") stopAlarm() } startAlarm() diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt index a717e79b49..dee77051fd 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt @@ -63,6 +63,7 @@ class ExtendedBolusDialog : DialogFragmentWithDate() { activity?.let { activity -> OKDialog.showConfirmation(activity, MainApp.gs(R.string.extended_bolus), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), Runnable { + log.debug("USER ENTRY: EXTENDED BOLUS $insulinAfterConstraint duration: $durationInMinutes") ConfigBuilderPlugin.getPlugin().commandQueue.extendedBolus(insulinAfterConstraint, durationInMinutes, object : Callback() { override fun run() { if (!result.success) { diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt index 273d0b800d..a840384de0 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt @@ -102,13 +102,16 @@ class FillDialog : DialogFragmentWithDate() { activity?.let { activity -> OKDialog.showConfirmation(activity, MainApp.gs(R.string.primefill), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), Runnable { if (insulinAfterConstraints > 0) { + log.debug("USER ENTRY: PRIME BOLUS $insulinAfterConstraints") requestPrimeBolus(insulinAfterConstraints, notes) } if (siteChange) { + log.debug("USER ENTRY: SITE CHANGE") generateCareportalEvent(CareportalEvent.SITECHANGE, eventTime, notes) } if (insulinChange) { // add a second for case of both checked + log.debug("USER ENTRY: INSULIN CHANGE") generateCareportalEvent(CareportalEvent.INSULINCHANGE, eventTime + 1000, notes) } }, null) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt index d6f64d87f1..42bc395b8b 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt @@ -147,6 +147,7 @@ class InsulinDialog : DialogFragmentWithDate() { activity?.let { activity -> OKDialog.showConfirmation(activity, MainApp.gs(R.string.bolus), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), Runnable { if (eatingSoonChecked) { + log.debug("USER ENTRY: TEMPTARGET EATING SOON $eatingSoonTT duration: $eatingSoonTTDuration") val tempTarget = TempTarget() .date(System.currentTimeMillis()) .duration(eatingSoonTTDuration) @@ -164,9 +165,11 @@ class InsulinDialog : DialogFragmentWithDate() { detailedBolusInfo.source = Source.USER detailedBolusInfo.notes = notes if (recordOnlyChecked) { + log.debug("USER ENTRY: BOLUS RECORD ONLY $insulinAfterConstraints") detailedBolusInfo.date = time TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false) } else { + log.debug("USER ENTRY: BOLUS $insulinAfterConstraints") detailedBolusInfo.date = DateUtil.now() ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() { override fun run() { diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt index 5df248593c..f594564a78 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt @@ -97,6 +97,7 @@ class ProfileSwitchDialog : DialogFragmentWithDate() { activity?.let { activity -> OKDialog.showConfirmation(activity, MainApp.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), Runnable { + log.debug("USER ENTRY: PROFILE SWITCH $profile percent: $percent timeshift: $timeShift duration: $duration") ProfileFunctions.doProfileSwitch(profileStore, profile, duration.toInt(), percent, timeShift, eventTime) }) } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt index dc31349650..d821aec56b 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt @@ -104,8 +104,10 @@ class TempBasalDialog : DialogFragmentWithDate() { } } if (isPercentPump) { + log.debug("USER ENTRY: TEMP BASAL $percent% duration: $durationInMinutes") ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalPercent(percent, durationInMinutes, true, profile, callback) } else { + log.debug("USER ENTRY: TEMP BASAL $absolute duration: $durationInMinutes") ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalAbsolute(absolute, durationInMinutes, true, profile, callback) } }) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt index 5408105a71..77cb0b6823 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt @@ -127,6 +127,7 @@ class TempTargetDialog : DialogFragmentWithDate() { activity?.let { activity -> OKDialog.showConfirmation(activity, MainApp.gs(R.string.careportal_temporarytarget), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), Runnable { + log.debug("USER ENTRY: TEMP TARGET $target duration: $duration") if (target == 0.0 || duration == 0.0) { val tempTarget = TempTarget() .date(eventTime) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt index 8667befaf2..565a65f54f 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt @@ -99,6 +99,7 @@ class TreatmentDialog : DialogFragmentWithDate() { if (insulinAfterConstraints > 0 || carbsAfterConstraints > 0) { activity?.let { activity -> OKDialog.showConfirmation(activity, MainApp.gs(R.string.overview_treatment_label), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), Runnable { + log.debug("USER ENTRY: BOLUS insulin $insulin carbs: $carbs") val detailedBolusInfo = DetailedBolusInfo() if (insulinAfterConstraints == 0.0) detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION if (carbsAfterConstraints == 0) detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt index 4977cd6f9f..e68df84fdf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt @@ -27,6 +27,7 @@ import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.dialogs.ProfileSwitchDialog import info.nightscout.androidaps.dialogs.TempTargetDialog +import info.nightscout.androidaps.logging.L import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.* @@ -34,9 +35,11 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import kotlinx.android.synthetic.main.actions_fragment.* import kotlinx.android.synthetic.main.careportal_stats_fragment.* +import org.slf4j.LoggerFactory import java.util.* class ActionsFragment : Fragment() { + private val log = LoggerFactory.getLogger(L.CORE) private var disposable: CompositeDisposable = CompositeDisposable() @@ -67,6 +70,7 @@ class ActionsFragment : Fragment() { } actions_extendedbolus_cancel.setOnClickListener { if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress) { + log.debug("USER ENTRY: CANCEL EXTENDED BOLUS") ConfigBuilderPlugin.getPlugin().commandQueue.cancelExtended(object : Callback() { override fun run() { if (!result.success) { @@ -86,6 +90,7 @@ class ActionsFragment : Fragment() { } actions_canceltempbasal.setOnClickListener { if (TreatmentsPlugin.getPlugin().isTempBasalInProgress) { + log.debug("USER ENTRY: CANCEL TEMP BASAL") ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() { override fun run() { if (!result.success) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java index 931cca544b..0976755f06 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java @@ -667,6 +667,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, return true; final LoopPlugin loopPlugin = LoopPlugin.getPlugin(); if (item.getTitle().equals(MainApp.gs(R.string.disableloop))) { + log.debug("USER ENTRY: LOOP DISABLED"); loopPlugin.setPluginEnabled(PluginType.LOOP, false); loopPlugin.setFragmentVisible(PluginType.LOOP, false); ConfigBuilderPlugin.getPlugin().storeSettings("DisablingLoop"); @@ -682,6 +683,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, LoopPlugin.getPlugin().createOfflineEvent(24 * 60); // upload 24h, we don't know real duration return true; } else if (item.getTitle().equals(MainApp.gs(R.string.enableloop))) { + log.debug("USER ENTRY: LOOP ENABLED"); loopPlugin.setPluginEnabled(PluginType.LOOP, true); loopPlugin.setFragmentVisible(PluginType.LOOP, true); ConfigBuilderPlugin.getPlugin().storeSettings("EnablingLoop"); @@ -690,6 +692,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, return true; } else if (item.getTitle().equals(MainApp.gs(R.string.resume)) || item.getTitle().equals(MainApp.gs(R.string.reconnect))) { + log.debug("USER ENTRY: RESUME"); loopPlugin.suspendTo(0L); updateGUI("suspendmenu"); ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { @@ -704,39 +707,48 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, LoopPlugin.getPlugin().createOfflineEvent(0); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor1h))) { + log.debug("USER ENTRY: SUSPEND 1h"); LoopPlugin.getPlugin().suspendLoop(60); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor2h))) { + log.debug("USER ENTRY: SUSPEND 2h"); LoopPlugin.getPlugin().suspendLoop(120); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor3h))) { + log.debug("USER ENTRY: SUSPEND 3h"); LoopPlugin.getPlugin().suspendLoop(180); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor10h))) { + log.debug("USER ENTRY: SUSPEND 10h"); LoopPlugin.getPlugin().suspendLoop(600); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor15m))) { + log.debug("USER ENTRY: DISCONNECT 15m"); LoopPlugin.getPlugin().disconnectPump(15, profile); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor30m))) { + log.debug("USER ENTRY: DISCONNECT 30m"); LoopPlugin.getPlugin().disconnectPump(30, profile); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor1h))) { + log.debug("USER ENTRY: DISCONNECT 1h"); LoopPlugin.getPlugin().disconnectPump(60, profile); SP.putBoolean(R.string.key_objectiveusedisconnect, true); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor2h))) { + log.debug("USER ENTRY: DISCONNECT 2h"); LoopPlugin.getPlugin().disconnectPump(120, profile); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor3h))) { + log.debug("USER ENTRY: DISCONNECT 3h"); LoopPlugin.getPlugin().disconnectPump(180, profile); updateGUI("suspendmenu"); return true; @@ -754,6 +766,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, if (manager != null) pvd.show(manager, "ProfileViewDialog"); } else if (item.getTitle().equals(MainApp.gs(R.string.eatingsoon))) { + log.debug("USER ENTRY: TEMP TARGET EATING SOON"); double target = Profile.toMgdl(DefaultValueHelper.determineEatingSoonTT(), ProfileFunctions.getSystemUnits()); TempTarget tempTarget = new TempTarget() .date(System.currentTimeMillis()) @@ -764,6 +777,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, .high(target); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); } else if (item.getTitle().equals(MainApp.gs(R.string.activity))) { + log.debug("USER ENTRY: TEMP TARGET ACTIVITY"); double target = Profile.toMgdl(DefaultValueHelper.determineActivityTT(), ProfileFunctions.getSystemUnits()); TempTarget tempTarget = new TempTarget() .date(now()) @@ -774,6 +788,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, .high(target); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); } else if (item.getTitle().equals(MainApp.gs(R.string.hypo))) { + log.debug("USER ENTRY: TEMP TARGET HYPO"); double target = Profile.toMgdl(DefaultValueHelper.determineHypoTT(), ProfileFunctions.getSystemUnits()); TempTarget tempTarget = new TempTarget() .date(now()) @@ -788,6 +803,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, if (manager != null) new TempTargetDialog().show(manager, "Overview"); } else if (item.getTitle().equals(MainApp.gs(R.string.cancel))) { + log.debug("USER ENTRY: TEMP TARGET CANCEL"); TempTarget tempTarget = new TempTarget() .source(Source.USER) .date(now()) @@ -907,6 +923,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun; if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.isChangeRequested()) { OKDialog.showConfirmation(context, MainApp.gs(R.string.pump_tempbasal_label), finalLastRun.constraintsProcessed.toSpanned(), () -> { + log.debug("USER ENTRY: ACCEPT TEMP BASAL"); hideTempRecommendation(); clearNotification(); LoopPlugin.getPlugin().acceptChangeRequest(); diff --git a/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt b/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt index 6d71a80ba1..ea4da238cb 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt @@ -277,6 +277,7 @@ class BolusWizard @JvmOverloads constructor(val profile: Profile, OKDialog.showConfirmation(context, MainApp.gs(R.string.boluswizard), HtmlHelper.fromHtml(confirmMessage), Runnable { if (insulinAfterConstraints > 0 || carbs > 0) { if (useSuperBolus) { + log.debug("USER ENTRY: SUPERBOLUS TBR") val loopPlugin = LoopPlugin.getPlugin() if (loopPlugin.isEnabled(PluginType.LOOP)) { loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000) @@ -325,6 +326,7 @@ class BolusWizard @JvmOverloads constructor(val profile: Profile, detailedBolusInfo.boluscalc = nsJSON() detailedBolusInfo.source = Source.USER detailedBolusInfo.notes = notes + log.debug("USER ENTRY: BOLUS insulin $insulinAfterConstraints carbs: $carbs") if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription?.storesCarbInfo == true) { ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() { override fun run() { From d5a7db8be73ff6ad9df33136c33d0ef827c39f00 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 4 Feb 2020 22:25:58 +0100 Subject: [PATCH 11/56] 2.6-dev-a --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index b5e47ec4ae..53b0398a43 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -109,7 +109,7 @@ android { targetSdkVersion 28 multiDexEnabled true versionCode 1500 - version "2.6-dev" + version "2.6-dev-a" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"' buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"' From 7b984550ea198ebc4f052ed03cf227783965c04b Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 4 Feb 2020 22:25:28 +0100 Subject: [PATCH 12/56] New Crowdin translations (#2423) * New translations strings.xml (Korean) * New translations objectives.xml (Korean) * New translations objectives.xml (Korean) * New translations strings.xml (Slovenian) * New translations insight_alert_codes.xml (Slovenian) * New translations insight_alert_descriptions.xml (Slovenian) * New translations insight_alert_titles.xml (Slovenian) * New translations insight_exceptions.xml (Slovenian) * New translations exam.xml (Slovenian) * New translations objectives.xml (Slovenian) * New translations strings.xml (Slovenian) * New translations strings.xml (French) * New translations strings.xml (Korean) * New translations exam.xml (Korean) * New translations strings.xml (Portuguese, Brazilian) * New translations strings.xml (Russian) * New translations strings.xml (Korean) * New translations strings.xml (Korean) * New translations strings.xml (German) * New translations strings.xml (Italian) --- app/src/main/res/values-de-rDE/strings.xml | 5 +++++ app/src/main/res/values-it-rIT/strings.xml | 4 ++++ app/src/main/res/values-ko-rKR/exam.xml | 6 +++--- app/src/main/res/values-ko-rKR/objectives.xml | 8 ++++---- app/src/main/res/values-ko-rKR/strings.xml | 15 +++++++++----- app/src/main/res/values-pt-rBR/strings.xml | 2 ++ app/src/main/res/values-ru-rRU/strings.xml | 5 +++++ app/src/main/res/values-sl-rSI/exam.xml | 3 +++ .../res/values-sl-rSI/insight_alert_codes.xml | 3 +++ .../insight_alert_descriptions.xml | 3 +++ .../values-sl-rSI/insight_alert_titles.xml | 3 +++ .../res/values-sl-rSI/insight_exceptions.xml | 3 +++ app/src/main/res/values-sl-rSI/objectives.xml | 3 +++ app/src/main/res/values-sl-rSI/strings.xml | 20 +++++++++++++++++++ wear/src/main/res/values-fr-rFR/strings.xml | 2 +- wear/src/main/res/values-sl-rSI/strings.xml | 3 +++ 16 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 app/src/main/res/values-sl-rSI/exam.xml create mode 100644 app/src/main/res/values-sl-rSI/insight_alert_codes.xml create mode 100644 app/src/main/res/values-sl-rSI/insight_alert_descriptions.xml create mode 100644 app/src/main/res/values-sl-rSI/insight_alert_titles.xml create mode 100644 app/src/main/res/values-sl-rSI/insight_exceptions.xml create mode 100644 app/src/main/res/values-sl-rSI/objectives.xml create mode 100644 app/src/main/res/values-sl-rSI/strings.xml create mode 100644 wear/src/main/res/values-sl-rSI/strings.xml diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index ad2e7a7629..8673afb35a 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -946,6 +946,7 @@ Starte deine erste Zielsetzung Berechtigung Nach Berechtigung fragen + Die App benötigt die Systemberechtigung für App-Benachrichtigungen AndroidAPS benötigt die Standortfreigabe für den BT-Scan. AndroidAPS benötigt Zugriff auf den Speicher, um Log-Dateien speichern zu können. Anfordern @@ -1450,4 +1451,8 @@ Unerwartetes Verhalten. \"PhoneChecker\" Diagrammmenü AS + SMB Anfragezeit + SMB Ausführungszeit + Temp. BR Anfragezeit + Temp. BR Ausführungszeit diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 8f8afcf3b8..cbf0f50945 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -1449,4 +1449,8 @@ \"PhoneChecker\" Menu grafico AS + Tempo richiesta SMB + Tempo esecuzione SMB + Tempo richiesta basale temporanea + Tempo esecuzione basale temporanea diff --git a/app/src/main/res/values-ko-rKR/exam.xml b/app/src/main/res/values-ko-rKR/exam.xml index 2b76f2c396..dfdfb154d8 100644 --- a/app/src/main/res/values-ko-rKR/exam.xml +++ b/app/src/main/res/values-ko-rKR/exam.xml @@ -131,12 +131,12 @@ 변경사항을 적용하는데 프로파일에서 ISF 값 변경하는 것으로 충분합니다. https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Getting-Started/FAQ.html#insulin-sensitivity-factor-isf-mmol-l-u-or-mg-dl-u https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Usage/Profiles.html - Topic: IC(인슐린 대 탄수화물) 비율 + 주제: IC(인슐린-탄수화물 비) 높은 IC 비율은 탄수화물 섭취시 인슐린이 보다 덜 주입되게 합니다. 낮은 IC 비율은 탄수화물 섭취시 인슐린이 보다 덜 주입되게 합니다. COB가 0 인 경우 IC 비율을 변경하면 혈당을 교정하기 위해 다른 양의 인슐린이 주입됩니다. - Bread Unit을 10g 혹은 12g으로 계산한다면 IC 값도 달라집니다. - IC의 의미는 다음과 같습니다: 1U의 인슐린에 대한 적정 Bread Unit 양 + 빵유닛(Bread Unit)을 10g 혹은 12g으로 계산한다면 IC 값도 달라집니다. + IC의 의미는 다음과 같습니다: 1U의 인슐린으로 얼마나 많은 빵유닛(Bread Units)이 처리되는지. https://androidaps.readthedocs.io/en/latest/CROWDIN/ko/Getting-Started/FAQ.html#carbohydrate-to-insulin-ratio-cr-g-u 주제: 프로파일 변경 프로파일을 90%로 설정하면 어떻게 됩니까? diff --git a/app/src/main/res/values-ko-rKR/objectives.xml b/app/src/main/res/values-ko-rKR/objectives.xml index 4bc1ebbb35..08c2a7f8d8 100644 --- a/app/src/main/res/values-ko-rKR/objectives.xml +++ b/app/src/main/res/values-ko-rKR/objectives.xml @@ -28,13 +28,13 @@ 완료: %1$s AndroidAPS를 사용하는 방법을 배워봅니다 AndroidAPS에서 다양한 작업을 수행해보세요 - 10분동안 프로파일 90%를 설정해보세요(개요에서 프로파일명을 길게 눌러보세요) - 샤워한다고 가정하고 펌프를 1시간 동안 펌프를 일시중지하세요 (개요에서 Open Loop를 길게 눌러보세요) + 10분동안 프로파일 90%를 설정해보세요(홈에서 프로파일명을 길게 눌러보세요) + 샤워한다고 가정하고 펌프를 1시간 동안 펌프를 일시중지하세요 (홈에서 Open Loop를 길게 눌러보세요) ... 그리고 같은 방법으로 펌프를 재연결하세요 - 10분의 사용자정의 임시 목표를 생성해 보세요 (개요에서 본인의 현재 목표혈당을 길게 눌러보세요) + 사용자정의 임시 목표를 10분동안 실행해보세요 (홈에서 본인의 현재 목표혈당을 길게 눌러보세요) 구성관리자에서 실행 플러그인을 활성화하고 메뉴에서 표시되게 합니다 Loop 플러그인 내용을 표시합니다 - 개요의 혈당 차트를 길게 눌러 차트 시간을 변경하세요 + 홈의 혈당 차트를 길게 눌러 차트 시간을 변경하세요 입력 당신이 OpenAPS 사용자였고 당신의 NS가 최소 3개월의 Loop 데이터가 저장되어 있다면, objectives@androidaps.org로 메일을 보내 당신의 NS주소를 알려주시고 목표를 건너뛸 수 있는 코드를 요청하세요. 그리고 개발자로 부터 받은 코드를 입력하세요. 코드 인증 diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index e4ecfc6ed9..066b4aee6b 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -273,7 +273,7 @@ 임시 목표 취소가 완료되었습니다 %1$.2fU 주입중 SMS 원격 명령 사용하기 - 체혈 + 채혈 센서 수동 임시 목표 @@ -641,7 +641,7 @@ 알리지 않은 식사 감지 IOB 커브 피크 시간 피크 시간 [min] - 자유-피크 Oref + 사용자지정-피크 Oref 초속효성 Oref 초-초속효성 Oref DIA %1$f는 너무 짧습니다. 대신 %2$f을 사용하세요! @@ -783,15 +783,15 @@ %1$.2f 시간 %1$d 분 - 항상 SMB를 사용합니다. + 항상 SMB 사용하기 Bolus와 독립적으로 항상 SMB를 사용합니다. G5처럼 잘 필터된 혈당소스와만 사용이 가능합니다. 탄수화물 이후 SMB를 사용합니다. 탄수화물 이후 6시간동안 SMB를 사용합니다, 0 COB이라도 적용됩니다. G5처럼 잘 필터된 혈당소스와만 사용이 가능합니다. COB와 SMB를 사용합니다. 활성화된 COB가 있으면 SMB를 사용합니다. - 임시 목표와 SMB를 사용합니다. + 임시 목표에서 SMB 사용하기 활성화된 임시 목표(식사직전, 운동)가 있으면 SMB를 사용합니다. - 높은임시 목표와 SMB를 사용합니다. + 높은 임시 목표에서 SMB 사용하기 활성화된 높은 임시 목표(운동)가 있으면 SMB를 사용합니다. 임시Basal 허용 음소거 @@ -946,6 +946,7 @@ 첫번째 목표를 시작하세요. 권한 권한 요청하기 + 알림에 대한 시스템 창 권한이 필요합니다 블루투스 스캔을 위해 위치 권한이 필요로 합니다. 로그 파일을 저장하기 위해 저장공간 권한이 필요로 합니다. 요청 @@ -1449,4 +1450,8 @@ \"전화확인\" 차트 메뉴 AS + SMB 요청시간 + SMB 실행시간 + 임시 Basal 요청시간 + 임시 Basal 실행시간 diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index aecda3ee0e..1e7dd42d16 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -1447,4 +1447,6 @@ Closed Loop desabilitado por causa da execução do Bólus Estendido BE \"VerificadorTelefone\" + Menu do Gráfico + AS diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index c717182dc4..860db5a999 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -948,6 +948,7 @@ Context | Edit Context Начните первую Цель Права доступа Запросить права доступа + Приложению требуется разрешение системного окна для уведомлений Приложение нуждается в разрешении на доступ к определению местоположения для сканирования bluetooth Приложение нуждается в разрешении доступа к хранению данных для хранения лог-файлов Запрос @@ -1451,4 +1452,8 @@ Context | Edit Context \"PhoneChecker\" Меню графика Авточувств + Время запроса микроболюса SMB + Время выполнения микроболюса SMB + Время запроса временной базальной скорости + Время выполнения временной базальной скорости diff --git a/app/src/main/res/values-sl-rSI/exam.xml b/app/src/main/res/values-sl-rSI/exam.xml new file mode 100644 index 0000000000..70489fbc5e --- /dev/null +++ b/app/src/main/res/values-sl-rSI/exam.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/res/values-sl-rSI/insight_alert_codes.xml b/app/src/main/res/values-sl-rSI/insight_alert_codes.xml new file mode 100644 index 0000000000..70489fbc5e --- /dev/null +++ b/app/src/main/res/values-sl-rSI/insight_alert_codes.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/res/values-sl-rSI/insight_alert_descriptions.xml b/app/src/main/res/values-sl-rSI/insight_alert_descriptions.xml new file mode 100644 index 0000000000..70489fbc5e --- /dev/null +++ b/app/src/main/res/values-sl-rSI/insight_alert_descriptions.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/res/values-sl-rSI/insight_alert_titles.xml b/app/src/main/res/values-sl-rSI/insight_alert_titles.xml new file mode 100644 index 0000000000..70489fbc5e --- /dev/null +++ b/app/src/main/res/values-sl-rSI/insight_alert_titles.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/res/values-sl-rSI/insight_exceptions.xml b/app/src/main/res/values-sl-rSI/insight_exceptions.xml new file mode 100644 index 0000000000..70489fbc5e --- /dev/null +++ b/app/src/main/res/values-sl-rSI/insight_exceptions.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/res/values-sl-rSI/objectives.xml b/app/src/main/res/values-sl-rSI/objectives.xml new file mode 100644 index 0000000000..70489fbc5e --- /dev/null +++ b/app/src/main/res/values-sl-rSI/objectives.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/res/values-sl-rSI/strings.xml b/app/src/main/res/values-sl-rSI/strings.xml new file mode 100644 index 0000000000..df88c88e20 --- /dev/null +++ b/app/src/main/res/values-sl-rSI/strings.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/values-fr-rFR/strings.xml b/wear/src/main/res/values-fr-rFR/strings.xml index 8318132564..27b90d0687 100644 --- a/wear/src/main/res/values-fr-rFR/strings.xml +++ b/wear/src/main/res/values-fr-rFR/strings.xml @@ -35,7 +35,7 @@ Afficher Min Passées Sombre Surbrillance Basale - Séparateur Noir + Séparateur Invisible Echelle Graphique 1 heure 2 heures diff --git a/wear/src/main/res/values-sl-rSI/strings.xml b/wear/src/main/res/values-sl-rSI/strings.xml new file mode 100644 index 0000000000..70489fbc5e --- /dev/null +++ b/wear/src/main/res/values-sl-rSI/strings.xml @@ -0,0 +1,3 @@ + + + From 42c2d89f987c8819c369940fad89d15568ade9db Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 6 Feb 2020 21:24:19 +0100 Subject: [PATCH 13/56] ask for overlay permission on android 10 only --- .../androidaps/utils/AndroidPermission.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java b/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java index d884552ac4..41e26e8e3b 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java @@ -133,20 +133,20 @@ public class AndroidPermission { } public static synchronized void notifyForSystemWindowPermissions(Activity activity) { - if (!Settings.canDrawOverlays(activity)) { - NotificationWithAction notification = new NotificationWithAction(Notification.PERMISSION_SYSTEM_WINDOW, MainApp.gs(R.string.needsystemwindowpermission), Notification.URGENT); - notification.action(R.string.request, () -> { - // Check if Android Q or higher - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - // Show alert dialog to the user saying a separate permission is needed - // Launch the settings activity if the user prefers - Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, - Uri.parse("package:" + activity.getPackageName())); - activity.startActivity(intent); - } - }); - RxBus.INSTANCE.send(new EventNewNotification(notification)); - } else - RxBus.INSTANCE.send(new EventDismissNotification(Notification.PERMISSION_SYSTEM_WINDOW)); + // Check if Android Q or higher + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + if (!Settings.canDrawOverlays(activity)) { + NotificationWithAction notification = new NotificationWithAction(Notification.PERMISSION_SYSTEM_WINDOW, MainApp.gs(R.string.needsystemwindowpermission), Notification.URGENT); + notification.action(R.string.request, () -> { + // Show alert dialog to the user saying a separate permission is needed + // Launch the settings activity if the user prefers + Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + Uri.parse("package:" + activity.getPackageName())); + activity.startActivity(intent); + }); + RxBus.INSTANCE.send(new EventNewNotification(notification)); + } else + RxBus.INSTANCE.send(new EventDismissNotification(Notification.PERMISSION_SYSTEM_WINDOW)); + } } } From 9098eb2da0661a6dc3e01341aa47884b208b9356 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 9 Feb 2020 13:04:49 +0100 Subject: [PATCH 14/56] save Careportal events directly to DB --- .../plugins/pump/insight/LocalInsightPlugin.java | 12 ++++++++++++ .../pump/medtronic/data/MedtronicHistoryData.java | 6 ++++++ .../plugins/source/SourceDexcomPlugin.kt | 15 +++++++++++++++ .../plugins/source/SourceEversensePlugin.java | 7 +++++++ 4 files changed, 40 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java index 5104e70fe8..afca125092 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java @@ -1524,6 +1524,12 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con data.put("created_at", DateUtil.toISOString(date)); data.put("eventType", CareportalEvent.NOTE); data.put("notes", note); + CareportalEvent careportalEvent = new CareportalEvent(); + careportalEvent.date = date; + careportalEvent.source = Source.USER; + careportalEvent.eventType = CareportalEvent.NOTE; + careportalEvent.json = data.toString(); + MainApp.getDbHelper().createOrUpdate(careportalEvent); NSUpload.uploadCareportalEntryToNS(data); } catch (JSONException e) { log.error("Unhandled exception", e); @@ -1552,6 +1558,12 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con if (!enteredBy.equals("")) data.put("enteredBy", enteredBy); data.put("created_at", DateUtil.toISOString(date)); data.put("eventType", event); + CareportalEvent careportalEvent = new CareportalEvent(); + careportalEvent.date = date; + careportalEvent.source = Source.USER; + careportalEvent.eventType = event; + careportalEvent.json = data.toString(); + MainApp.getDbHelper().createOrUpdate(careportalEvent); NSUpload.uploadCareportalEntryToNS(data); } catch (JSONException e) { log.error("Unhandled exception", e); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java index 11d1bad3d9..39c44167a2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java @@ -528,6 +528,12 @@ public class MedtronicHistoryData { if (!enteredBy.equals("")) data.put("enteredBy", enteredBy); data.put("created_at", DateUtil.toISOString(date)); data.put("eventType", event); + CareportalEvent careportalEvent = new CareportalEvent(); + careportalEvent.date = date; + careportalEvent.source = Source.USER; + careportalEvent.eventType = event; + careportalEvent.json = data.toString(); + MainApp.getDbHelper().createOrUpdate(careportalEvent); NSUpload.uploadCareportalEntryToNS(data); } catch (JSONException e) { LOG.error("Unhandled exception", e); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/SourceDexcomPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/SourceDexcomPlugin.kt index 633f16cf10..bf5661ad00 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/SourceDexcomPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/SourceDexcomPlugin.kt @@ -9,6 +9,8 @@ import info.nightscout.androidaps.R import info.nightscout.androidaps.activities.RequestDexcomPermissionActivity import info.nightscout.androidaps.db.BgReading import info.nightscout.androidaps.db.CareportalEvent +import info.nightscout.androidaps.db.Source +import info.nightscout.androidaps.dialogs.CareDialog import info.nightscout.androidaps.interfaces.BgSourceInterface import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.PluginDescription @@ -96,6 +98,13 @@ object SourceDexcomPlugin : PluginBase(PluginDescription() jsonObject.put("glucoseType", "Finger") jsonObject.put("glucose", meter.getInt("meterValue")) jsonObject.put("units", Constants.MGDL) + + val careportalEvent = CareportalEvent() + careportalEvent.date = timestamp + careportalEvent.source = Source.USER + careportalEvent.eventType = CareportalEvent.BGCHECK + careportalEvent.json = jsonObject.toString() + MainApp.getDbHelper().createOrUpdate(careportalEvent) NSUpload.uploadCareportalEntryToNS(jsonObject) } } @@ -110,6 +119,12 @@ object SourceDexcomPlugin : PluginBase(PluginDescription() jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType") jsonObject.put("created_at", DateUtil.toISOString(sensorInsertionTime)) jsonObject.put("eventType", CareportalEvent.SENSORCHANGE) + val careportalEvent = CareportalEvent() + careportalEvent.date = sensorInsertionTime + careportalEvent.source = Source.USER + careportalEvent.eventType = CareportalEvent.SENSORCHANGE + careportalEvent.json = jsonObject.toString() + MainApp.getDbHelper().createOrUpdate(careportalEvent) NSUpload.uploadCareportalEntryToNS(jsonObject) } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/SourceEversensePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/source/SourceEversensePlugin.java index 6f39e3d762..6d0067414a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/SourceEversensePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/SourceEversensePlugin.java @@ -15,6 +15,7 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; @@ -143,6 +144,12 @@ public class SourceEversensePlugin extends PluginBase implements BgSourceInterfa data.put("glucoseType", "Finger"); data.put("glucose", calibrationGlucoseLevels[i]); data.put("units", Constants.MGDL); + CareportalEvent careportalEvent = new CareportalEvent(); + careportalEvent.date = calibrationTimestamps[i]; + careportalEvent.source = Source.USER; + careportalEvent.eventType = CareportalEvent.BGCHECK; + careportalEvent.json = data.toString(); + MainApp.getDbHelper().createOrUpdate(careportalEvent); NSUpload.uploadCareportalEntryToNS(data); } } catch (JSONException e) { From f111b731e75a86edafd2ddb8424a01b718691ab8 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 9 Feb 2020 22:16:48 +0100 Subject: [PATCH 15/56] Improve SetupWizardTest to be runnable on real device --- app/build.gradle | 1 + .../nightscout/androidaps/EspressoHelper.kt | 8 +++ .../androidaps/SetupWizardActivityTest.kt | 61 +++++++++++-------- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 53b0398a43..69ae9369cb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -315,6 +315,7 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test:rules:1.3.0-alpha03' androidTestImplementation 'com.google.code.findbugs:jsr305:3.0.2' + androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0' } diff --git a/app/src/androidTest/java/info/nightscout/androidaps/EspressoHelper.kt b/app/src/androidTest/java/info/nightscout/androidaps/EspressoHelper.kt index b50bb746fb..cf7118ebd2 100644 --- a/app/src/androidTest/java/info/nightscout/androidaps/EspressoHelper.kt +++ b/app/src/androidTest/java/info/nightscout/androidaps/EspressoHelper.kt @@ -4,6 +4,9 @@ import androidx.test.espresso.ViewAction import androidx.test.espresso.ViewInteraction import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.UiSelector fun ViewInteraction.isDisplayed(): Boolean { try { @@ -25,3 +28,8 @@ fun ViewInteraction.waitAndPerform(viewActions: ViewAction): ViewInteraction? { return perform(viewActions) } +fun clickOkInDialog() { + val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + val button = uiDevice.findObject(UiSelector().clickable(true).checkable(false).index(1)) + if (button.exists() && button.isEnabled) button.click() +} diff --git a/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt b/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt index dd1c0b12bc..a2742c2a34 100644 --- a/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt +++ b/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt @@ -1,6 +1,5 @@ package info.nightscout.androidaps - import android.os.SystemClock import android.view.View import android.view.ViewGroup @@ -9,12 +8,15 @@ import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.scrollTo -import androidx.test.espresso.matcher.ViewMatchers.* +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withClassName +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withTagValue +import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import androidx.test.rule.ActivityTestRule import androidx.test.rule.GrantPermissionRule -import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin @@ -39,7 +41,6 @@ import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith - @LargeTest @RunWith(AndroidJUnit4::class) class SetupWizardActivityTest { @@ -50,12 +51,12 @@ class SetupWizardActivityTest { @Rule @JvmField - var mGrantPermissionRule = - GrantPermissionRule.grant( - android.Manifest.permission.ACCESS_FINE_LOCATION, - android.Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, - android.Manifest.permission.WRITE_EXTERNAL_STORAGE - ) + var mGrantPermissionRule: GrantPermissionRule = + GrantPermissionRule.grant( + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, + android.Manifest.permission.WRITE_EXTERNAL_STORAGE + ) @Before fun clear() { @@ -74,9 +75,9 @@ adb shell settings put global transition_animation_scale 0 & adb shell settings put global animator_duration_scale 0 & */ - @Test fun setupWizardActivityTest() { + SP.clear() Assert.assertTrue(isRunningTest()) // Welcome page onView(withId(R.id.next_button)).perform(click()) @@ -86,7 +87,7 @@ adb shell settings put global animator_duration_scale 0 & // Agreement page onView(withText("I UNDERSTAND AND AGREE")).perform(scrollTo(), click()) onView(withId(R.id.next_button)).waitAndPerform(click()) - // Loction permission + // Location permission var askButton = onView(withText("Ask for permission")) if (askButton.isDisplayed()) { askButton.perform(scrollTo(), click()) @@ -99,6 +100,11 @@ adb shell settings put global animator_duration_scale 0 & onView(withText("OK")).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click()) } + // Import settings : skip of found + askButton = onView(withText("IMPORT SETTINGS")) + if (askButton.isDisplayed()) { + onView(withId(R.id.next_button)).waitAndPerform(click()) + } // Units selection onView(withText("mmol/L")).perform(scrollTo(), click()) onView(withId(R.id.next_button)).perform(click()) @@ -125,41 +131,44 @@ adb shell settings put global animator_duration_scale 0 & // Local profile - IC onView(withId(R.id.ic_tab)).perform(scrollTo(), click()) onView(Matchers.allOf(withTagValue(Matchers.`is`("IC-1-0")), isDisplayed())) - .perform(ViewActions.replaceText("2"), ViewActions.closeSoftKeyboard()) + .perform(ViewActions.replaceText("2"), ViewActions.closeSoftKeyboard()) // Local profile - ISF onView(withId(R.id.isf_tab)).perform(scrollTo(), click()) onView(Matchers.allOf(withTagValue(Matchers.`is`("ISF-1-0")), isDisplayed())) - .perform(ViewActions.replaceText("3"), ViewActions.closeSoftKeyboard()) + .perform(ViewActions.replaceText("3"), ViewActions.closeSoftKeyboard()) // Local profile - BAS onView(withId(R.id.basal_tab)).perform(scrollTo(), click()) onView(childAtPosition(Matchers.allOf(withId(R.id.localprofile_basal), childAtPosition(withClassName(Matchers.`is`("android.widget.LinearLayout")), 6)), 2)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) onView(Matchers.allOf(withTagValue(Matchers.`is`("BASAL-1-0")), isDisplayed())) - .perform(ViewActions.replaceText("1.1"), ViewActions.closeSoftKeyboard()) + .perform(ViewActions.replaceText("1.1"), ViewActions.closeSoftKeyboard()) onView(Matchers.allOf(withTagValue(Matchers.`is`("BASAL-1-1")), isDisplayed())) - .perform(ViewActions.replaceText("1.2"), ViewActions.closeSoftKeyboard()) + .perform(ViewActions.replaceText("1.2"), ViewActions.closeSoftKeyboard()) onView(Matchers.allOf(withId(R.id.timelistedit_time), childAtPosition(childAtPosition(withId(R.id.localprofile_basal), 2), 0))) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) onData(Matchers.anything()).inAdapterView(childAtPosition(withClassName(Matchers.`is`("android.widget.PopupWindow\$PopupBackgroundView")), 0)).atPosition(13) - .perform(click()) + .perform(click()) // Local profile - TARGET onView(withId(R.id.target_tab)).perform(scrollTo(), click()) onView(Matchers.allOf(withTagValue(Matchers.`is`("TARGET-1-0")), isDisplayed())) - .perform(ViewActions.replaceText("6"), ViewActions.closeSoftKeyboard()) + .perform(ViewActions.replaceText("6"), ViewActions.closeSoftKeyboard()) onView(Matchers.allOf(withTagValue(Matchers.`is`("TARGET-2-0")), isDisplayed())) - .perform(ViewActions.replaceText("6.5"), ViewActions.closeSoftKeyboard()) + .perform(ViewActions.replaceText("6.5"), ViewActions.closeSoftKeyboard()) onView(withText("Save")).perform(scrollTo(), click()) onView(Matchers.allOf(withId(R.id.localprofile_profileswitch), isDisplayed())) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) onView(allOf(withId(R.id.ok), isDisplayed())).perform(click()) - onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) + // confirm dialog + //onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) not working on real phone + clickOkInDialog() onView(withId(R.id.next_button)).waitAndPerform(click()) // Profile switch askButton = onView(withText("Do Profile Switch")) if (askButton.isDisplayed()) { askButton.perform(scrollTo(), click()) onView(allOf(withId(R.id.ok), isDisplayed())).perform(click()) - onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) + // onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) not working on real phone + clickOkInDialog() while (ProfileFunctions.getInstance().profile == null) SystemClock.sleep(100) onView(withId(R.id.next_button)).waitAndPerform(click()) } @@ -204,7 +213,7 @@ adb shell settings put global animator_duration_scale 0 & } private fun childAtPosition( - parentMatcher: Matcher, position: Int): Matcher { + parentMatcher: Matcher, position: Int): Matcher { return object : TypeSafeMatcher() { override fun describeTo(description: Description) { @@ -215,7 +224,7 @@ adb shell settings put global animator_duration_scale 0 & public override fun matchesSafely(view: View): Boolean { val parent = view.parent return parent is ViewGroup && parentMatcher.matches(parent) - && view == parent.getChildAt(position) + && view == parent.getChildAt(position) } } } From 0ff7702b1a29fa6016e3b3e9011094fc17e9b396 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 11 Feb 2020 17:06:30 +0100 Subject: [PATCH 16/56] RealPumpTest| --- app/build.gradle | 30 +++++ .../nightscout/androidaps/RealPumpTest.kt | 116 ++++++++++++++++++ .../nightscout/androidaps/MainActivity.java | 4 +- .../androidaps/interfaces/PluginBase.java | 2 +- .../plugins/source/RandomBgPlugin.kt | 6 +- .../androidaps/utils/EspressoTestHelper.kt | 10 ++ 6 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 app/src/androidTest/java/info/nightscout/androidaps/RealPumpTest.kt diff --git a/app/build.gradle b/app/build.gradle index 69ae9369cb..7d622ed56f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -343,6 +343,36 @@ task full_clean(type: Delete) { delete file("src/main/jniLibs") } +// Run 'adb' shell command to clear application data of main app for 'debug' variant +task clearMainAppData(type: Exec) { + // we have to iterate to find the 'debug' variant to obtain a variant reference + android.applicationVariants.all { variant -> + if (variant.name == "fullDebug") { + def applicationId = [variant.mergedFlavor.applicationId, variant.buildType.applicationIdSuffix].findAll().join() + def clearDataCommand = ['adb', 'shell', 'pm', 'clear', applicationId] + println "Clearing application data of ${variant.name} variant: [${clearDataCommand}]" + def stdout = new ByteArrayOutputStream() + exec { + commandLine clearDataCommand + standardOutput = stdout + } + String result = stdout.toString().trim() + if (!result.startsWith("Success")) { + println result + throw new GradleException(clearDataCommand.join(" ")) + } + } + } +} +// Clear Application Data (once) before running instrumentation test +tasks.whenTaskAdded { task -> + // Both of these targets are equivalent today, although in future connectedCheck + // will also include connectedUiAutomatorTest (not implemented yet) + if(task.name == "connectedAndroidTest" || task.name == "connectedCheck"){ + task.dependsOn(clearMainAppData) + } +} + clean.dependsOn full_clean preBuild.dependsOn copyLibs diff --git a/app/src/androidTest/java/info/nightscout/androidaps/RealPumpTest.kt b/app/src/androidTest/java/info/nightscout/androidaps/RealPumpTest.kt new file mode 100644 index 0000000000..5463fbcd26 --- /dev/null +++ b/app/src/androidTest/java/info/nightscout/androidaps/RealPumpTest.kt @@ -0,0 +1,116 @@ +package info.nightscout.androidaps + +import android.os.SystemClock +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.LargeTest +import androidx.test.rule.ActivityTestRule +import androidx.test.rule.GrantPermissionRule +import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.interfaces.PumpInterface +import info.nightscout.androidaps.logging.L +import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin +import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions +import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin +import info.nightscout.androidaps.plugins.general.actions.ActionsPlugin +import info.nightscout.androidaps.plugins.insulin.InsulinOrefUltraRapidActingPlugin +import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin +import info.nightscout.androidaps.plugins.pump.danaRv2.DanaRv2Plugin +import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin +import info.nightscout.androidaps.plugins.source.RandomBgPlugin +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.SP +import info.nightscout.androidaps.utils.isRunningTest +import org.json.JSONObject +import org.junit.Assert +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.slf4j.LoggerFactory + +@LargeTest +@RunWith(AndroidJUnit4::class) +class RealPumpTest { + + private val log = LoggerFactory.getLogger(L.CORE) + + companion object { + val pump: PumpInterface = DanaRv2Plugin.getPlugin() + const val R_PASSWORD = 1234 + const val R_SERIAL = "PBB00013LR_P" + } + + private val validProfile = "{\"dia\":\"6\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"10\"},{\"time\":\"2:00\",\"value\":\"11\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + + @Rule + @JvmField + var mActivityTestRule = ActivityTestRule(MainActivity::class.java) + + @Rule + @JvmField + var mGrantPermissionRule: GrantPermissionRule = + GrantPermissionRule.grant( + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, + android.Manifest.permission.WRITE_EXTERNAL_STORAGE + ) + + @Before + fun clear() { + SP.clear() + SP.putBoolean(R.string.key_setupwizard_processed, true) + SP.putString(R.string.key_aps_mode, "closed") + MainApp.getDbHelper().resetDatabases() + MainApp.devBranch = false + } + + private fun preparePlugins() { + // Source + RandomBgPlugin.performPluginSwitch(true, PluginType.BGSOURCE) + // Profile + LocalProfilePlugin.performPluginSwitch(true, PluginType.PROFILE) + val profile = Profile(JSONObject(validProfile), Constants.MGDL) + Assert.assertTrue(profile.isValid("Test")) + LocalProfilePlugin.profiles.clear() + LocalProfilePlugin.numOfProfiles = 0 + val singleProfile = LocalProfilePlugin.SingleProfile().copyFrom(profile, "TestProfile") + LocalProfilePlugin.addProfile(singleProfile) + ProfileFunctions.doProfileSwitch(LocalProfilePlugin.createProfileStore(), "TestProfile", 0, 100, 0, DateUtil.now()) + // Insulin + InsulinOrefUltraRapidActingPlugin.getPlugin().performPluginSwitch(true, PluginType.INSULIN) + // Pump + SP.putInt(R.string.key_danar_password, R_PASSWORD) + SP.putString(R.string.key_danar_bt_name, R_SERIAL) + (pump as PluginBase).performPluginSwitch(true, PluginType.PUMP) + // Sensitivity + SensitivityOref1Plugin.getPlugin().performPluginSwitch(true, PluginType.SENSITIVITY) + // APS + OpenAPSSMBPlugin.getPlugin().performPluginSwitch(true, PluginType.APS) + LoopPlugin.getPlugin().performPluginSwitch(true, PluginType.LOOP) + + // Enable common + ActionsPlugin.performPluginSwitch(true, PluginType.GENERAL) + + // Disable unneeded + MainApp.getPluginsList().remove(ObjectivesPlugin) + } + + @Test + fun doTest() { + Assert.assertTrue(isRunningTest()) + preparePlugins() + + while (!pump.isInitialized) { + log.debug("Waiting for initialization") + SystemClock.sleep(1000) + } + + while (true) { + log.debug("Tick") + SystemClock.sleep(1000) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index f74a58856f..c152c415cb 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -63,6 +63,8 @@ import info.nightscout.androidaps.utils.SP; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; +import static info.nightscout.androidaps.utils.EspressoTestHelperKt.isRunningRealPumpTest; + public class MainActivity extends NoSplashAppCompatActivity { private static Logger log = LoggerFactory.getLogger(L.CORE); private CompositeDisposable disposable = new CompositeDisposable(); @@ -137,7 +139,7 @@ public class MainActivity extends NoSplashAppCompatActivity { .subscribe(this::processPreferenceChange, FabricPrivacy::logException) ); - if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) { + if (!SP.getBoolean(R.string.key_setupwizard_processed, false) && !isRunningRealPumpTest()) { Intent intent = new Intent(this, SetupWizardActivity.class); startActivity(intent); } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java b/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java index e236125255..5d4ec01fd9 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java @@ -74,7 +74,7 @@ public abstract class PluginBase { } } - private void performPluginSwitch(boolean enabled, PluginType type) { + public void performPluginSwitch(boolean enabled, PluginType type) { setPluginEnabled(type, enabled); setFragmentVisible(type, enabled); ConfigBuilderPlugin.getPlugin().processOnEnabledCategoryChanged(this, getType()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt index ea6731ca60..1f79b82bc6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt @@ -31,7 +31,7 @@ object RandomBgPlugin : PluginBase(PluginDescription() private val loopHandler = Handler() private lateinit var refreshLoop: Runnable - const val interval = 5L // minutes + const val interval = 1L // minutes init { refreshLoop = Runnable { @@ -55,7 +55,7 @@ object RandomBgPlugin : PluginBase(PluginDescription() } override fun specialEnableCondition(): Boolean { - return VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP) && (MainApp.engineeringMode || isRunningTest()) + return isRunningTest() || VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP) && MainApp.engineeringMode } override fun handleNewData(intent: Intent) { @@ -65,7 +65,7 @@ object RandomBgPlugin : PluginBase(PluginDescription() val cal = GregorianCalendar() val currentMinute = cal.get(Calendar.MINUTE) + (cal.get(Calendar.HOUR_OF_DAY) % 2) * 60 - val bgMgdl = min + (max - min) * sin(currentMinute / 120.0 * 2 * PI) + val bgMgdl = min + (max - min) + (max - min) * sin(currentMinute / 120.0 * 2 * PI) val bgReading = BgReading() bgReading.value = bgMgdl diff --git a/app/src/main/java/info/nightscout/androidaps/utils/EspressoTestHelper.kt b/app/src/main/java/info/nightscout/androidaps/utils/EspressoTestHelper.kt index 7288e6679f..0cddcc0792 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/EspressoTestHelper.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/EspressoTestHelper.kt @@ -9,3 +9,13 @@ fun isRunningTest(): Boolean { false } } + +@Synchronized +fun isRunningRealPumpTest(): Boolean { + return try { + Class.forName("info.nightscout.androidaps.RealPumpTest") + true + } catch (e: ClassNotFoundException) { + false + } +} From 7b0ea23b40fc2fb880fa24e42f963cb893110525 Mon Sep 17 00:00:00 2001 From: Brian Quinion Date: Thu, 20 Feb 2020 16:08:51 +0000 Subject: [PATCH 17/56] Require the connection to NS to be encrypted (unless in engineering mode) --- .../plugins/general/nsclient/services/NSClientService.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java index e1c57cc7c2..4c5b9f36bb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java @@ -274,7 +274,7 @@ public class NSClientService extends Service { } else if (!nsEnabled) { RxBus.INSTANCE.send(new EventNSClientNewLog("NSCLIENT", "disabled")); RxBus.INSTANCE.send(new EventNSClientStatus("Disabled")); - } else if (!nsURL.equals("")) { + } else if (!nsURL.equals("") && (MainApp.engineeringMode || nsURL.toLowerCase().startsWith("https://"))) { try { RxBus.INSTANCE.send(new EventNSClientStatus("Connecting ...")); IO.Options opt = new IO.Options(); @@ -295,6 +295,9 @@ public class NSClientService extends Service { RxBus.INSTANCE.send(new EventNSClientNewLog("NSCLIENT", "Wrong URL syntax")); RxBus.INSTANCE.send(new EventNSClientStatus("Wrong URL syntax")); } + } else if (nsURL.toLowerCase().startsWith("http://")) { + RxBus.INSTANCE.send(new EventNSClientNewLog("NSCLIENT", "NS URL not encrypted")); + RxBus.INSTANCE.send(new EventNSClientStatus("Not encrypted")); } else { RxBus.INSTANCE.send(new EventNSClientNewLog("NSCLIENT", "No NS URL specified")); RxBus.INSTANCE.send(new EventNSClientStatus("Not configured")); From 43495e2565d5bd809ae6a133379e2aa863d06508 Mon Sep 17 00:00:00 2001 From: Brian Quinion Date: Thu, 20 Feb 2020 16:38:41 +0000 Subject: [PATCH 18/56] Expose error messages where NS connection fails --- .../general/nsclient/services/NSClientService.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java index 4c5b9f36bb..3a38e15ec4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java @@ -283,6 +283,9 @@ public class NSClientService extends Service { mSocket = IO.socket(nsURL, opt); mSocket.on(Socket.EVENT_CONNECT, onConnect); mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect); + mSocket.on(Socket.EVENT_ERROR, onError); + mSocket.on(Socket.EVENT_CONNECT_ERROR, onError); + mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onError); mSocket.on(Socket.EVENT_PING, onPing); RxBus.INSTANCE.send(new EventNSClientNewLog("NSCLIENT", "do connect")); mSocket.connect(); @@ -395,6 +398,13 @@ public class NSClientService extends Service { nsDevice = SP.getString("careportal_enteredby", ""); } + private Emitter.Listener onError = new Emitter.Listener() { + @Override + public void call(final Object... args) { + RxBus.INSTANCE.send(new EventNSClientNewLog("ERROR", args[0].toString())); + } + }; + private Emitter.Listener onPing = new Emitter.Listener() { @Override public void call(final Object... args) { From 385781de2381b93165f65096b01b82953bf61400 Mon Sep 17 00:00:00 2001 From: Brian Quinion Date: Thu, 20 Feb 2020 16:56:56 +0000 Subject: [PATCH 19/56] Validate paramaters in onError in NS Client --- .../plugins/general/nsclient/services/NSClientService.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java index 3a38e15ec4..565399dd59 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java @@ -401,7 +401,11 @@ public class NSClientService extends Service { private Emitter.Listener onError = new Emitter.Listener() { @Override public void call(final Object... args) { - RxBus.INSTANCE.send(new EventNSClientNewLog("ERROR", args[0].toString())); + String msg = "Unknown Error"; + if (args.length > 0 && args[0] != null) { + msg = args[0].toString(); + } + RxBus.INSTANCE.send(new EventNSClientNewLog("ERROR", msg)); } }; From b11707b5d44c12756138e73f43a5130fb5b4d3e4 Mon Sep 17 00:00:00 2001 From: sabsoubi Date: Fri, 21 Feb 2020 11:04:59 +0100 Subject: [PATCH 20/56] Fixed Bug that doesn't show COB if BGI disabled. --- .../general/xdripStatusline/StatuslinePlugin.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatuslinePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatuslinePlugin.java index da61b83b98..bd5b7e4eab 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatuslinePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatuslinePlugin.java @@ -202,13 +202,13 @@ public class StatuslinePlugin extends PluginBase { + DecimalFormatter.to2Decimal(basalIob.basaliob) + ")"; } - if (!mPrefs.getBoolean("xdripstatus_showbgi", false)) { - return status; + // BGI + if (mPrefs.getBoolean("xdripstatus_showbgi", true)) { + double bgi = -(bolusIob.activity + basalIob.activity) * 5 * profile.getIsf(); + status += " " + ((bgi >= 0) ? "+" : "") + DecimalFormatter.to2Decimal(bgi); } - double bgi = -(bolusIob.activity + basalIob.activity) * 5 * profile.getIsf(); - - status += " " + ((bgi >= 0) ? "+" : "") + DecimalFormatter.to2Decimal(bgi); + /* COB */ status += " " + IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "StatuslinePlugin").generateCOBString(); return status; From 3b9ea53cc4f0f65eec3c698afe3e8a3e6f075432 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 25 Feb 2020 20:46:04 +0100 Subject: [PATCH 21/56] Fix TempTarget confirm dialog --- .../nightscout/androidaps/dialogs/TempTargetDialog.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt index 77cb0b6823..5b1dd48692 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt @@ -114,11 +114,11 @@ class TempTargetDialog : DialogFragmentWithDate() { val reason = overview_temptarget_reason.selectedItem.toString() val unitResId = if (ProfileFunctions.getSystemUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol val target = overview_temptarget_temptarget.value - val duration = overview_temptarget_duration.value - if (target != 0.0 && duration != 0.0) { + val duration = overview_temptarget_duration.value.toInt() + if (target != 0.0 && duration != 0) { actions.add(MainApp.gs(R.string.reason) + ": " + reason) actions.add(MainApp.gs(R.string.nsprofileview_target_label) + ": " + Profile.toCurrentUnitsString(target) + " " + MainApp.gs(unitResId)) - actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_hours, duration)) + actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_mins, duration)) } else { actions.add(MainApp.gs(R.string.stoptemptarget)) } @@ -128,7 +128,7 @@ class TempTargetDialog : DialogFragmentWithDate() { activity?.let { activity -> OKDialog.showConfirmation(activity, MainApp.gs(R.string.careportal_temporarytarget), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), Runnable { log.debug("USER ENTRY: TEMP TARGET $target duration: $duration") - if (target == 0.0 || duration == 0.0) { + if (target == 0.0 || duration == 0) { val tempTarget = TempTarget() .date(eventTime) .duration(0) @@ -145,7 +145,7 @@ class TempTargetDialog : DialogFragmentWithDate() { .high(Profile.toMgdl(target, ProfileFunctions.getSystemUnits())) TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget) } - if (duration == 10.0) SP.putBoolean(R.string.key_objectiveusetemptarget, true) + if (duration == 10) SP.putBoolean(R.string.key_objectiveusetemptarget, true) }) } return true From 832663081101188d20c3380cc8818d5f6fc7ec35 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 25 Feb 2020 21:30:44 +0100 Subject: [PATCH 22/56] Revert gradle changes for UI tests --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 7d622ed56f..0dd80641bf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -342,7 +342,7 @@ task copyLibs(dependsOn: downloadAndUnzipFile, type: Copy) { task full_clean(type: Delete) { delete file("src/main/jniLibs") } - +/* // Run 'adb' shell command to clear application data of main app for 'debug' variant task clearMainAppData(type: Exec) { // we have to iterate to find the 'debug' variant to obtain a variant reference @@ -372,7 +372,7 @@ tasks.whenTaskAdded { task -> task.dependsOn(clearMainAppData) } } - +*/ clean.dependsOn full_clean preBuild.dependsOn copyLibs From 26170ddea55401a2a15c60140365d40551b61b51 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 25 Feb 2020 21:54:14 +0100 Subject: [PATCH 23/56] New Crowdin translations (#2429) * New translations strings.xml (Swedish) * New translations strings.xml (Italian) * New translations strings.xml (Korean) * New translations strings.xml (German) * New translations strings.xml (Slovak) * New translations strings.xml (Korean) * New translations strings.xml (Korean) * New translations strings.xml (Portuguese) * New translations strings.xml (Korean) * New translations strings.xml (Korean) * New translations strings.xml (German) * New translations strings.xml (French) * New translations exam.xml (Dutch) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (Bulgarian) * New translations strings.xml (Korean) * New translations strings.xml (French) * New translations strings.xml (Spanish) * New translations strings.xml (Spanish) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) --- app/src/main/res/values-bg-rBG/strings.xml | 6 ++- app/src/main/res/values-de-rDE/strings.xml | 4 +- app/src/main/res/values-es-rES/strings.xml | 5 ++- app/src/main/res/values-fr-rFR/strings.xml | 42 ++++++++++++--------- app/src/main/res/values-it-rIT/strings.xml | 1 + app/src/main/res/values-ko-rKR/strings.xml | 37 +++++++++--------- app/src/main/res/values-nl-rNL/exam.xml | 4 +- app/src/main/res/values-pt-rPT/strings.xml | 5 +++ app/src/main/res/values-sk-rSK/strings.xml | 5 +++ app/src/main/res/values-sv-rSE/strings.xml | 7 ++++ wear/src/main/res/values-es-rES/strings.xml | 2 +- 11 files changed, 74 insertions(+), 44 deletions(-) diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index d3a01e2d86..78b71447fb 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -1,5 +1,4 @@ - @@ -946,6 +945,7 @@ Започнете първа цел Разрешение Питане за разрешение + ААПС изисква разрешение за да може да Ви уведомява Приложението се нуждае от достъп до вашето местоположение за да активира BT сканиране Приложението се нуждае от разрешение да съхранява данни за да може съхранява лог файлове Искане @@ -1449,4 +1449,8 @@ \"PhoneChecker\" Меню на графиката АS + Диапазон между изпълнение на SMB + Макс. време за изпълнение за SMB + Диапазон между временни базали + Продължителност на временни базали diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 8673afb35a..3ccf637260 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -846,7 +846,7 @@ Das Einlesen der geänderten Basalrate in der Pumpe schlug fehl Änderungen der Historie werden gesucht Der Import mehrerer Boli der gleichen Menge, abgegeben in der gleichen Minute, ist gescheitert: Nur ein Datensatz konnte den Behandlungen hinzugefügt werden. Bitte überprüfe die Pumpe und verwende das Careportal, um fehlende Einträge hinzuzufügen. Stelle sicher, dass keine Einträge für genau dieselbe Minute mit derselben Menge hinzugefügt werden. - \n\nhttp://www.androidaps.org\nhttp://www.androidaps.de (de)\n\nSupport:\nhttps://de.loopercommunity.org/ (de)\nhttp://facebook.androidaps.org + \n\nhttp://www.androidaps.org\nhttp://www.androidaps.de (de)\n\nSupport:\nhttps://de.loopercommunity.org/\nhttp://facebook.androidaps.org Der letzte Bolus liegt mehr als 24 Stunden zurück oder liegt in der Zukunft. Prüfe bitte das Datum auf der Pumpe. Zeit/Datum des abgegebenen Boluses auf der Pumpe erscheint falsch, IOB ist wahrscheinlich nicht korrekt. Bitte prüfe Zeit/Datum der Pumpe. Profil-Wechsel fehlt, bitte nimm einen Profil-Wechsel vor oder drücke \"AKTIVIERE PROFIL\" im lokalen Profil. @@ -1447,7 +1447,7 @@ Unerwartetes Verhalten. Warteschlange löschen? Alle Daten in der Warteschlange gehen verloren! Die Verwendung eines Verzögerungsbolus unterbricht dem Closed Loop Modus für die Dauer des Verzögerungsbolus. Willst Du das wirklich? Closed Loop wegen Verzögerungsbolus unterbrochen - VB + VerzB \"PhoneChecker\" Diagrammmenü AS diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 48e69e0564..9c4bd4d36a 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -1,5 +1,4 @@ - @@ -1446,4 +1445,8 @@ El uso de la función de bolo extendido detendrá el modo de bucle cerrado durante el tiempo de ejecución del bolo extendido. ¿Realmente quieres esto? Bucle cerrado inhabilitado debido a la ejecución del bolo extendido EB + Menú gráfico + AS + Tiempo requerido de SMB + Tiempo de ejecución de SMB diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index 2437913625..c398fc1990 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -1,5 +1,4 @@ - @@ -157,7 +156,7 @@ Changez vos entrées ! Source des glycémies Quelle source de données doit être utilisée par AndroidAPS ? - xDrip + xDrip+ Mode APS Boucle Fermée Boucle Ouverte @@ -196,7 +195,7 @@ Capteur Glucides Insuline - Heure glucides + Décalage horaire Diviser Durée Pourcentage @@ -220,7 +219,7 @@ Importer les paramètres Max. U/hr pour le débit temp Basal Cette valeur est appelée Basal Maximum dans le contexte OpenAPS - Le Basal IA maximum que l\'OpenAPS pourra délivrer [U] + IA basale max que OpenAPS pourra délivrer [U] Cette valeur est appelée Max IA (Insuline Active) dans le contexte OpenAPS\nC\'estlle maximum d\'insuline en [U] que APS peut délivrer en une seule fois. FERMER DanaR @@ -385,7 +384,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Renvoyer toutes les données Afficher les Paramètres sur la Montre Erreur Pompe - Niveau Batterie Bas + Piles Faibles Arrêt de la Pompe Batterie Pompe Déchargée DanaR Coréenne @@ -644,7 +643,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Temps du Pic [min] Profil d\'insuline ajustable Oref Insuline à Action Rapide Oref - Insuline à Action Ultra Rapide Oref + Insuline Ultra Rapide Oref Durée d’Action pour %1$f trop courte - utiliser %2$f à la place ! Activer le profil Date @@ -701,7 +700,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Pilote pompe corrigé Pompe hors de portée Valeurs de glycémie manquantes - Utiliser le système des notifications + Utiliser les notifications système pour les alertes et notifications Alertes locales Alerte pas nouvelle donnée glycémique Alerte si la pompe est hors de portée @@ -766,7 +765,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Historique pompe Définir le profil basal Niveau réservoir pompe bas - Niveau batterie pompe bas + Pile pompe faible La pompe affiche l’erreur E%1$d: %2$s Bas Vide @@ -885,7 +884,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S réinitialiser En attente de synchronisation de l\'heure (%1$d sec) Déconnecté (%1$d m) - Maximum Insuline Active IA pour OpenAPS [U] + IA totale maximale pour OpenAPS [U] Cette valeur est appelée Max IA (Insuline Active) dans le contaxte OpenAPS\nOpenAPS n’ajoutera pas plus d’insuline si l\'IA (Insuline Active) actuelle est supérieure à cette valeur Pompe arrêtée Pompe démarrée @@ -909,15 +908,15 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S MGC Utilisez uniquement connexion Wi-fi Wi-fi SSID - Wi-fi uniquement pendant la charge + Uniquement si en charge Paramètres de connexion SSIDs autorisés (séparés par point-virgule) Autoriser connexion données itinérance Maximum Ratio Autosens Minimum Ratio Autosens - Diviseur de Bolus snooze DIA - Maximum multiplicateur quotidien de sécurité - Multiplicateur actuel de sécurité du Basal + Snooze bolus Diviseur de DAI + Multiplicateur max quotidien de sécurité + Multiplicateur de sécurité basale courante ND Type de pompe virtuelle Définition de pompe @@ -947,6 +946,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Démarrez votre premier objectif Autorisation Demande d\'autorisation + L\'application a besoin de l\'autorisation d\'accès à la fenêtre système pour les notifications L\'application requiert l\'autorisation de localisation pour le balayage Bluetooth L\'application requiert une autorisation de stockage de données afin de pouvoir sauvegarder les fichiers journaux Demande @@ -1015,7 +1015,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Erreur de commande Erreur de vitesse Violation d\'une limite d\'insuline - Changement minimum possible [%] + Changement minimum [%] Le fonctionnement de la Boucle demandera une confirmation uniquement si le changement est supérieur à cette valeur en %. Par défaut, la valeur est 20% Appairez SVP votre pompe avec votre téléphone ! Recherche d\'appareils en cours… @@ -1244,7 +1244,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Mondial (868 Mhz) Encodage logiciel 4b6b Encodage matériel 4b6b - Réveil et mise au point + Réveil et Réglage Effacer le bloc Bolus Réinitialiser la config. RileyLink Type de batterie (vue d\'alimentation) @@ -1270,8 +1270,8 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Paramètres Historique - Statut du RileyLink - Statut de la pompe + État du RileyLink + État de la pompe Paramètres RileyLink RileyLink Adresse configurée @@ -1300,7 +1300,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Bluetooth est désactivé Aucun adaptateur Bluetooth Échec du réglage - Pompe inaccessible + Pompe hors de portée Pod inaccessible Non configuré @@ -1448,4 +1448,10 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Boucle fermée désactivée à cause du bolus étendu EB \"Vérif. du téléphone\" + Menu Graph + AS + Heure de demande SMB + Heure d\'exécution SMB + Heure de demande basal temp + Heure d\'exécution basal temp diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index cbf0f50945..952633064b 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -946,6 +946,7 @@ Avvia il tuo primo obiettivo Permesso Chiedi il permesso + L\'applicazione richiede il permesso finestra di sistema per le notifiche L\'applicazione richiede l\'accesso alla posizione per eseguire lo scan bluetooth L\'applicazione richiede l\'accesso alla memoria per salvare i file di log Richiesta diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 066b4aee6b..66e4215fe6 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -1,5 +1,4 @@ - @@ -105,7 +104,7 @@ 근거 혈당 증분 - 증분: + Delta: 구성 관리자 목표 OpenAPS MA @@ -155,7 +154,7 @@ Basal: 탄수화물 입력값을 변경하세요! - 혈당 소스 + 혈당 출처 AndroidAPS가 어디에서 데이터를 가져옵니까? xDrip APS 모드 @@ -183,7 +182,7 @@ 인슐린 카트리지 교체 프로파일 변경 간식Bolus - 식사Bolus + Meal Bolus 교정Bolus 콤보Bolus 임시Basal 시작 @@ -254,7 +253,7 @@ 허가된 전화번호 +XXXXXXXXXX;+YYYYYYYYYY Bolus %1$.2fU 을 주입하려면 %2$s 를 입력하고 답장하세요 - 식사Bolus %1$.2f을 주입하려면 %2$s를 입력하고 답장하세요 + MEAL Bolus %1$.2f을 주입하려면 %2$s를 입력하고 답장하세요 임시목표 %1$s를 설정하려면 %2$s를 입력하고 답장하세요 임시목표를 취소하려면 %1$s를 입력하고 답장하세요 SMS 원격 기능을 비활성화려면 %1$s를 입력하고 답장하세요.\n\nAAPS 마스터폰을 통해서만 다시 활성화할 수 있습니다. @@ -267,7 +266,7 @@ Bolus %1$.2fU이 주입 완료되었습니다. %1$.2fU을 주입합니다 Bolus %1$.2fU이 주입 완료되었습니다 - 식사Bolus %1$.2f이 주입 완료되었습니다 + Meal Bolus %1$.2f이 주입 완료되었습니다 %2$d 분 동안 목표 %1$s %2$d 분 동안 목표 %1$s 설정이 완료되었습니다 임시 목표 취소가 완료되었습니다 @@ -328,24 +327,24 @@ 원격 명령이 허가되지 않았습니다 원격 주입이 불가능합니다. 나중에 다시 시도해주세요. %2$d분 동안 Basal %1$.2fU/h 주입하려면 %3$s 를 입력하고 답장하세요 - 프로파일을 %1$s %2$d%%로 변경하려면 %3$s 를 입력하고 답장하세요 + 프로파일 %1$s %2$d%%로 변경하려면 %3$s 를 입력하고 답장하세요 %2$d분 동안 확장 Bolus %1$.2fU 주입하려면 %3$s 를 입력하고 답장하세요 %2$s에 %1$dg을 입력하려면 %3$s를 입력하고 답장하세요 %2$d 분 동안 Basal %1$d%% 주입하려면 %3$s을 입력하고 답장하세요 %1$d분동안 Loop 일시중지하려면 %2$s 를 입력하고 답장하세요 Temp Basal %1$.2fU/h for %2$d min started successfully - %2$d분 동안 확장Bolus %1$.2fU주입이 성공적으로 시작되었습니다 + Extended bolus %1$.2fU for %2$d min started successfully 탄수화물 %1$dg 입력이 완료되었습니다 탄수화물 %1$dg 입력이 실패하였습니다 - %2$d분 동안 임시Basal %1$d%%주입이 성공적으로 시작되었습니다 + Temp basal %1$d%% for %2$d min started successfully Temp Basal start failed - 확장 Bolus 실행 실패 + Extended bolus start failed 임시Basal을 중지하려면 %1$s 를 입력하고 답장하세요 확장 Bolus를 중지하려면 %1$s 를 입력하고 답장하세요 Temp Basal canceled - 확장 Bolus 취소 + Extended bolus canceled Canceling Temp Basal failed - 확장 Bolus 취소가 실패하였습니다. + Canceling extended bolus failed 알려지지 않은 명령이거나 잘못된 답장입니다 빠른마법사 빠른마법사 설정 @@ -355,12 +354,12 @@ 추가 수정 삭제 - 식사 + Meal 교정주입 실행 AndroidAPS 시작 NS에 업로드만 하기(동기화 안됨) - NS에 업로드만 하기. 로컬소스(xDrip)가 선택되지 않으면 SGV에는 효력이 없습니다. NS프로파일이 사용중이라면 프로파일에는 효력이 없습니다. + NS에 업로드만 하기. xDrip같은 로컬 혈당 출처가 선택되지 않다면 SGV에는 효력이 없습니다. NS프로파일이 사용중이라면 프로파일에는 효력이 없습니다. 펌프가 초기화 되지 않았습니다! 펌프가 초기화와 프로파일 설정이 되지 않았습니다! 교체/채움 @@ -668,7 +667,7 @@ 임시목표 기본값 식사직전 기간 식사직전 목표 - activity 기간 + 활동 기간 활동 목표 저혈당 기간 저혈당 목표 @@ -784,9 +783,9 @@ %1$.2f 시간 %1$d 분 항상 SMB 사용하기 - Bolus와 독립적으로 항상 SMB를 사용합니다. G5처럼 잘 필터된 혈당소스와만 사용이 가능합니다. + Bolus와 독립적으로 항상 SMB를 사용합니다. G5처럼 잘 필터된 혈당출처와만 사용이 가능합니다. 탄수화물 이후 SMB를 사용합니다. - 탄수화물 이후 6시간동안 SMB를 사용합니다, 0 COB이라도 적용됩니다. G5처럼 잘 필터된 혈당소스와만 사용이 가능합니다. + 탄수화물 이후 6시간동안 SMB를 사용합니다, 0 COB이라도 적용됩니다. G5처럼 잘 필터된 혈당출처와만 사용이 가능합니다. COB와 SMB를 사용합니다. 활성화된 COB가 있으면 SMB를 사용합니다. 임시 목표에서 SMB 사용하기 @@ -878,7 +877,7 @@ 상태를 읽지 못했습니다. 펌프 위치 변경 기록 인슐린 카트리지 변경 기록 - 선택한 BG 소스가 고급 필터링을 지원하지 않기 때문에 SMB가 항상 비활성화됩니다. + 선택한 혈당 출처가 고급 필터링을 지원하지 않기 때문에 SMB가 항상 비활성화됩니다. Open Loop모드에선 SMB가 허용되지 않습니다. Food 재설정 @@ -940,7 +939,7 @@ https://github.com/MilosKozak/AndroidAPS/wiki/Sensitivity-detection-and-COB NSClient는 Nightscout와의 연결을 처리합니다. 이 부분을 건너뛸 수 있지만 설정하기 전엔 목적을 수행할 수 없습니다. 새로운 인슐린 프로파일은 최소 5시간의 DIA가 요구됩니다. 새로운 프로파일의 DIA 5-6시간은 구식 인슐린 프로파일의 DIA 3시간과 동일합니다. - 혈당소스 설정하기 + 혈당 출처 설정하기 프로파일 소스를 선택해주세요. 당뇨인이 어린이라면 NS 프로파일을 선택하여야 합니다. Nightscout으로 관리해줄 사람이 없다면 당신은 로컬 프로파일을 선호할 수도 있습니다. 여기선 프로파일의 소스를 선택할 뿐이라는 것을 명심하세요. 그 프로파일을 실제 사용하려면 \"프로파일 변경\"을 실행하여 프로파일을 활성화 시켜야합니다. 사용 가능한 알고리즘 중 하나를 선택하세요. 과거부터 최신의 순으로 정렬이 되어 있습니다. 일반적으로 새로운 알고리즘은 보다 강력하고 공격적입니다. 따라서 당신이 신규 사용자라면 최신의 알고리즘보단 AMA로 시작하는것이 나을 수 있습니다. 사용 전에 OpenAPS 문서를 읽어보고 설정하는 것을 잊지마세요. 첫번째 목표를 시작하세요. diff --git a/app/src/main/res/values-nl-rNL/exam.xml b/app/src/main/res/values-nl-rNL/exam.xml index 9768183305..eefa78bba3 100644 --- a/app/src/main/res/values-nl-rNL/exam.xml +++ b/app/src/main/res/values-nl-rNL/exam.xml @@ -122,7 +122,7 @@ xDrip app in volg-modus. Loop app op de iPhone. Spike app op de iPhone. - https://androidaps.readthedocs.io/en/latest/CROWDIN/nl/Children/kinderen.html + https://androidaps.readthedocs.io/en/latest/CROWDIN/nl/Children/Children.html Onderwerp: Insulinegevoeligheidsfactor Hogere ISF-waarden leiden tot minder insulineafgifte wanneer AAPS voor hoge BG corrigeert. Lagere ISF-waarden leiden tot minder insulineafgifte wanneer AAPS voor hoge BG corrigeert. @@ -130,7 +130,7 @@ U moet ISF invoeren in Instellingen. Het wijzigen van de ISF-waarde in uw profiel is voldoende om de wijziging toe te passen. https://androidaps.readthedocs.io/en/latest/CROWDIN/nl/Getting-Started/FAQ.html#insuline-gevoeligheids-factor-insulin-sensitivity-factor-ISF-mmol-l-E-of-mg-dl-E - https://androidaps.readthedocs.io/en/latest/CROWDIN/nl/Usage/Profielen.html + https://androidaps.readthedocs.io/en/latest/CROWDIN/nl/Usage/Profiles.html Onderwerp: De KH ratio Hogere KH ratios leiden tot minder insuline afgifte voor een bepaalde hoeveelheid koolhydraten. Lagere KH ratios leiden tot minder insuline afgifte voor een bepaalde hoeveelheid koolhydraten. diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index d2c3a9d519..313f6c6658 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -946,6 +946,7 @@ Iniciar primeiro objectivo Permissão Pedir permissão + Aplicação precisa de permissão de janela do sistema para notificações Aplicação requer permissão de localização para pesquisa BT Aplicação necessita da permissão de armazenamento para ser capaz de armazenar ficheiros de registo Pedido @@ -1449,4 +1450,8 @@ \"VerificadorTelefone\" Menu do Gráfico AS + Hora de solicitação SMB + Hora de execução do SMB + Hora de solicitação Basal Temp + Hora de execução Basal Temp diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml index 38500ca8a2..0b8fdca2e3 100644 --- a/app/src/main/res/values-sk-rSK/strings.xml +++ b/app/src/main/res/values-sk-rSK/strings.xml @@ -946,6 +946,7 @@ Spusťte prvý cieľ Povolenie Vyžiadať si povolenie + Aplikácia vyžaduje pre oznámenia systémové oprávnenie Aplikácia vyžaduje povolenie \"polohy\", aby mohla vyhľadávať BT zariadenia Aplikácia vyžaduje prístup k úložisku, aby mohla ukladať logy Požiadavka @@ -1449,4 +1450,8 @@ PhoneChecker Grafové menu AS + Čas požiadavky SMB + Čas aplikácie SMB + Čas požiadavky dočasného bazálu + Čas spustenia dočasného bazálu diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index ec0e76b738..96b45303a9 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -947,6 +947,7 @@ Eversense-appen. Påbörja ditt första mål Behörighet Be om behörighet + Applikationen behöver förhöjd behörighet för aviseringar Appen behöver behörighet att använda Platsinfo för att kunna söka efter Bluetooth-enheter Appen behöver behörighet att använda Lagring för att kunna spara loggfiler Begäran @@ -1448,4 +1449,10 @@ Eversense-appen. Closed Loop-läget inaktiverat pga att en förlängd bolus är aktiv FB Telefonkontroll + Diagrammeny + AS + SMB begärd + SMB utförd + Basalförändring begärd + Basalförändring utförd diff --git a/wear/src/main/res/values-es-rES/strings.xml b/wear/src/main/res/values-es-rES/strings.xml index af200da3fb..6e65157335 100644 --- a/wear/src/main/res/values-es-rES/strings.xml +++ b/wear/src/main/res/values-es-rES/strings.xml @@ -1,5 +1,4 @@ - AAPS AAPS @@ -51,6 +50,7 @@ Bajo Medio Alto + Auto Números grandes Historial de Ring Historial de Ring Light From dfd3115b590262a6183bd0ec92c1c8ffd426ac5e Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 29 Feb 2020 21:32:06 +0100 Subject: [PATCH 24/56] gradle update --- .idea/codeStyles/Project.xml | 3 --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 48bbf82e58..d1c3d63de5 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,9 +1,6 @@ diff --git a/wear/src/main/res/values-it-rIT/strings.xml b/wear/src/main/res/values-it-rIT/strings.xml index 5247ee0674..0f7282e210 100644 --- a/wear/src/main/res/values-it-rIT/strings.xml +++ b/wear/src/main/res/values-it-rIT/strings.xml @@ -1,5 +1,4 @@ - AAPS AAPS @@ -98,7 +97,7 @@ TDD CHO IOB - no stato + no status mg/dl mmol/l g diff --git a/wear/src/main/res/values-nl-rNL/strings.xml b/wear/src/main/res/values-nl-rNL/strings.xml index e1e7c4c3d6..784fdb2f19 100644 --- a/wear/src/main/res/values-nl-rNL/strings.xml +++ b/wear/src/main/res/values-nl-rNL/strings.xml @@ -1,18 +1,109 @@ - + AAPS + AAPS + AAPS + AAPS(Groot) + AAPS(GroteGrafiek) + AAPS(GeenGrafiek) + AAPS(Cirkel) + AAPSv2 + AAPS(Cockpit) + AAPS(Steampunk) + Geen gegevens! + Oude gegevens! + Sinds %1$s + Synchroniseer met AAPS! + Geen gegevens ontvangen sinds %1$s! Controleer of AAPS op de telefoon gegevens verstuurt naar horloge AAPS gegevens zijn %1$s oud! Controleer je sensor, xDrip+, NS, AAPS instellingen of andere! Aan Uit Trillen bij bolus Eenheden voor acties Toon datum + Toon IOB + Toon COB Toon Delta Toon gemiddelde delta + Toon telefoonbatterij + Toon rig batterij + Toon basaal + Toon loop status + Toon BG + Toon richtingspijl + Toon tijd geleden + Donker + Markeer basaalstanden + Bijpassende verdeler + Tijdsschaal grafiek 1 uur 2 uren 3 uren 4 uren 5 uren + Invoer ontwerp Standaard + Snel rechts + Snel links + Modern spaarzaam + Delta schaalverdeling (Steampunk) + Laag + Middel + Hoog + Automatisch + Grote nummers + Ring geschiedenis + Lichte ring geschiedenis + Animaties + Wizard in menu + Ontlucht/vul in menu + Enkel streefdoel + Wizardpercentage + Complicatie tik voor actie + Unicode in complicaties + Versie: + TijdStreefd + Wizard + Bolus + eCarb + Instellingen + Status + Ontlucht/vul + Geen + Standaard + Menu + tijdsduur + doel + laag + hoog + khd + percentage + start [min] + duur [h] + insuline + Voorinstelling 1 + Voorinstelling 2 + Voorinstelling 3 + Vrije hoeveelheid + BEVESTIGEN + STATUS POMP + STATUS LOOP + tijdsverschuiving + Gewogen TDD + bolus + Pomp + Loop + CPP + TDD + Khd + IOB + geen status + mg/dl + mmol/l + g + E + E/u + u + d + w From 6fa05f11c92a3965e0a7d901220163afd4986089 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 6 Mar 2020 19:02:34 +0100 Subject: [PATCH 34/56] LocalInsightPlugin crash fix --- .../androidaps/plugins/pump/insight/LocalInsightPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java index 8dd425b12c..2197b48577 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java @@ -937,6 +937,7 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con @Override public JSONObject getJSONStatus(Profile profile, String profileName) { long now = System.currentTimeMillis(); + if (connectionService == null) return null; if (System.currentTimeMillis() - connectionService.getLastConnected() > (60 * 60 * 1000)) { return null; } From 95394d6cb370fb8f92f81af00b8183e4f269c9c8 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 6 Mar 2020 19:13:56 +0100 Subject: [PATCH 35/56] Unregister shared preferences properly --- .../androidaps/activities/PreferencesActivity.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java index 328f143836..96a2b23b06 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java @@ -68,6 +68,12 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this); } + @Override + protected void onDestroy() { + super.onDestroy(); + PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this); + } + @Override public void attachBaseContext(Context newBase) { super.attachBaseContext(LocaleHelper.INSTANCE.wrap(newBase)); From 4cca305e1bb9d7cba6f4672ca6e1756e8db5e1ac Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 6 Mar 2020 19:40:29 +0100 Subject: [PATCH 36/56] fix ProfileSwitch confirm dialog --- .../nightscout/androidaps/dialogs/ProfileSwitchDialog.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt index f594564a78..a258cbec8a 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt @@ -78,9 +78,9 @@ class ProfileSwitchDialog : DialogFragmentWithDate() { ?: return false val actions: LinkedList = LinkedList() - val duration = overview_profileswitch_duration.value + val duration = overview_profileswitch_duration.value.toInt() if (duration > 0) - actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_hours, duration)) + actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_mins, duration)) val profile = overview_profileswitch_profile.selectedItem.toString() actions.add(MainApp.gs(R.string.profile) + ": " + profile) val percent = overview_profileswitch_percentage.value.toInt() @@ -98,7 +98,7 @@ class ProfileSwitchDialog : DialogFragmentWithDate() { activity?.let { activity -> OKDialog.showConfirmation(activity, MainApp.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), Runnable { log.debug("USER ENTRY: PROFILE SWITCH $profile percent: $percent timeshift: $timeShift duration: $duration") - ProfileFunctions.doProfileSwitch(profileStore, profile, duration.toInt(), percent, timeShift, eventTime) + ProfileFunctions.doProfileSwitch(profileStore, profile, duration, percent, timeShift, eventTime) }) } return true From 70053ea61cca3faa2c585b064a8deb477fa469b7 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Fri, 6 Mar 2020 12:33:20 +0100 Subject: [PATCH 37/56] Combo: create separate bolus/carb records at driver level. --- .../plugins/pump/combo/ComboPlugin.java | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java index 32a17f8a89..e71a86d91f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java @@ -654,16 +654,29 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint * Creates a treatment record based on the request in DetailBolusInfo and the delivered bolus. */ private boolean addBolusToTreatments(DetailedBolusInfo detailedBolusInfo, Bolus lastPumpBolus) { - DetailedBolusInfo dbi = detailedBolusInfo.copy(); - dbi.date = calculateFakeBolusDate(lastPumpBolus); - dbi.pumpId = dbi.date; - dbi.source = Source.PUMP; - dbi.insulin = lastPumpBolus.amount; + DetailedBolusInfo bolusInfo = detailedBolusInfo.copy(); + bolusInfo.date = calculateFakeBolusDate(lastPumpBolus); + bolusInfo.pumpId = bolusInfo.date; + bolusInfo.source = Source.PUMP; + bolusInfo.insulin = lastPumpBolus.amount; try { - TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, true); + if (bolusInfo.carbs > 0 && bolusInfo.carbTime != 0) { + // split out a separate carbs record without a pumpId + DetailedBolusInfo carbInfo = new DetailedBolusInfo(); + carbInfo.date = bolusInfo.date + bolusInfo.carbTime * 60L * 1000L; + carbInfo.carbs = bolusInfo.carbs; + carbInfo.source = Source.USER; + TreatmentsPlugin.getPlugin().addToHistoryTreatment(carbInfo, true); + + // remove carbs from bolusInfo to not trigger any unwanted code paths in + // TreatmentsPlugin.addToHistoryTreatment() method + bolusInfo.carbTime = 0; + bolusInfo.carbs = 0; + } + TreatmentsPlugin.getPlugin().addToHistoryTreatment(bolusInfo, true); } catch (Exception e) { log.error("Adding treatment record failed", e); - if (dbi.isSMB) { + if (bolusInfo.isSMB) { Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_error_updating_treatment_record), Notification.URGENT); RxBus.INSTANCE.send(new EventNewNotification(notification)); } From 1e02773b71d0180bf30b6185c40b718ea268200f Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 6 Mar 2020 20:27:39 +0100 Subject: [PATCH 38/56] fire immediatelly TreatmentChange if not from NS --- .../plugins/treatments/TreatmentService.java | 66 ++++++++++++------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentService.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentService.java index 1331c8eedf..1b118da1d3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentService.java @@ -160,7 +160,7 @@ public class TreatmentService extends OrmLiteBaseService { } catch (SQLException e) { log.error("Unhandled exception", e); } - scheduleTreatmentChange(null); + scheduleTreatmentChange(null, true); } @@ -208,18 +208,30 @@ public class TreatmentService extends OrmLiteBaseService { /** * Schedule a foodChange Event. */ - public void scheduleTreatmentChange(@Nullable final Treatment treatment) { - this.scheduleEvent(new EventReloadTreatmentData(new EventTreatmentChange(treatment)), treatmentEventWorker, new ICallback() { - @Override - public void setPost(ScheduledFuture post) { - scheduledTreatmentEventPost = post; + public void scheduleTreatmentChange(@Nullable final Treatment treatment, boolean runImmediately) { + if (runImmediately) { + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("Firing EventReloadTreatmentData"); + RxBus.INSTANCE.send(new EventReloadTreatmentData(new EventTreatmentChange(treatment))); + if (DatabaseHelper.earliestDataChange != null) { + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("Firing EventNewHistoryData"); + RxBus.INSTANCE.send(new EventNewHistoryData(DatabaseHelper.earliestDataChange)); } + DatabaseHelper.earliestDataChange = null; + } else { + this.scheduleEvent(new EventReloadTreatmentData(new EventTreatmentChange(treatment)), treatmentEventWorker, new ICallback() { + @Override + public void setPost(ScheduledFuture post) { + scheduledTreatmentEventPost = post; + } - @Override - public ScheduledFuture getPost() { - return scheduledTreatmentEventPost; - } - }); + @Override + public ScheduledFuture getPost() { + return scheduledTreatmentEventPost; + } + }); + } } public List getTreatmentData() { @@ -294,7 +306,7 @@ public class TreatmentService extends OrmLiteBaseService { getDao().create(existingTreatment); DatabaseHelper.updateEarliestDataChange(oldDate); DatabaseHelper.updateEarliestDataChange(existingTreatment.date); - scheduleTreatmentChange(treatment); + scheduleTreatmentChange(treatment, true); return new UpdateReturn(sameSource, false); //updating a pump treatment with another one from the pump is not counted as clash } return new UpdateReturn(equalRePumpHistory, false); @@ -318,14 +330,14 @@ public class TreatmentService extends OrmLiteBaseService { getDao().create(existingTreatment); DatabaseHelper.updateEarliestDataChange(oldDate); DatabaseHelper.updateEarliestDataChange(existingTreatment.date); - scheduleTreatmentChange(treatment); + scheduleTreatmentChange(treatment, true); return new UpdateReturn(equalRePumpHistory || sameSource, false); } getDao().create(treatment); if (L.isEnabled(L.DATATREATMENTS)) log.debug("New record from: " + Source.getString(treatment.source) + " " + treatment.toString()); DatabaseHelper.updateEarliestDataChange(treatment.date); - scheduleTreatmentChange(treatment); + scheduleTreatmentChange(treatment, true); return new UpdateReturn(true, true); } if (treatment.source == Source.NIGHTSCOUT) { @@ -343,7 +355,7 @@ public class TreatmentService extends OrmLiteBaseService { DatabaseHelper.updateEarliestDataChange(oldDate); DatabaseHelper.updateEarliestDataChange(old.date); } - scheduleTreatmentChange(treatment); + scheduleTreatmentChange(treatment, false); return new UpdateReturn(true, true); } if (L.isEnabled(L.DATATREATMENTS)) @@ -366,7 +378,7 @@ public class TreatmentService extends OrmLiteBaseService { DatabaseHelper.updateEarliestDataChange(oldDate); DatabaseHelper.updateEarliestDataChange(old.date); } - scheduleTreatmentChange(treatment); + scheduleTreatmentChange(treatment, false); return new UpdateReturn(true, true); } if (L.isEnabled(L.DATATREATMENTS)) @@ -378,7 +390,7 @@ public class TreatmentService extends OrmLiteBaseService { if (L.isEnabled(L.DATATREATMENTS)) log.debug("New record from: " + Source.getString(treatment.source) + " " + treatment.toString()); DatabaseHelper.updateEarliestDataChange(treatment.date); - scheduleTreatmentChange(treatment); + scheduleTreatmentChange(treatment, false); return new UpdateReturn(true, true); } if (treatment.source == Source.USER) { @@ -386,7 +398,7 @@ public class TreatmentService extends OrmLiteBaseService { if (L.isEnabled(L.DATATREATMENTS)) log.debug("New record from: " + Source.getString(treatment.source) + " " + treatment.toString()); DatabaseHelper.updateEarliestDataChange(treatment.date); - scheduleTreatmentChange(treatment); + scheduleTreatmentChange(treatment, true); return new UpdateReturn(true, true); } } catch (SQLException e) { @@ -414,7 +426,7 @@ public class TreatmentService extends OrmLiteBaseService { if (L.isEnabled(L.DATATREATMENTS)) log.debug("New record from: " + Source.getString(treatment.source) + " " + treatment.toString()); DatabaseHelper.updateEarliestDataChange(treatment.date); - scheduleTreatmentChange(treatment); + scheduleTreatmentChange(treatment, true); return new UpdateReturn(true, true); } else { @@ -428,7 +440,7 @@ public class TreatmentService extends OrmLiteBaseService { } getDao().update(existingTreatment); DatabaseHelper.updateEarliestDataChange(existingTreatment.date); - scheduleTreatmentChange(treatment); + scheduleTreatmentChange(treatment, true); return new UpdateReturn(true, false); } else { if (MedtronicHistoryData.doubleBolusDebug) @@ -439,7 +451,7 @@ public class TreatmentService extends OrmLiteBaseService { optionalTreatmentCopy(existingTreatment, treatment, fromNightScout); getDao().create(existingTreatment); DatabaseHelper.updateEarliestDataChange(existingTreatment.date); - scheduleTreatmentChange(treatment); + scheduleTreatmentChange(treatment, true); return new UpdateReturn(true, false); //updating a pump treatment with another one from the pump is not counted as clash } } @@ -626,9 +638,13 @@ public class TreatmentService extends OrmLiteBaseService { if (stored != null) { if (L.isEnabled(L.DATATREATMENTS)) log.debug("Removing Treatment record from database: " + stored.toString()); - delete(stored); + try { + getDao().delete(stored); + } catch (SQLException e) { + log.error("Unhandled exception", e); + } DatabaseHelper.updateEarliestDataChange(stored.date); - scheduleTreatmentChange(null); + this.scheduleTreatmentChange(stored, false); } } @@ -643,7 +659,7 @@ public class TreatmentService extends OrmLiteBaseService { try { getDao().delete(treatment); DatabaseHelper.updateEarliestDataChange(treatment.date); - this.scheduleTreatmentChange(treatment); + this.scheduleTreatmentChange(treatment, true); } catch (SQLException e) { log.error("Unhandled exception", e); } @@ -656,7 +672,7 @@ public class TreatmentService extends OrmLiteBaseService { } catch (SQLException e) { log.error("Unhandled exception", e); } - scheduleTreatmentChange(treatment); + scheduleTreatmentChange(treatment, true); } /** From a3ee216b215eafe9137bb26ad7c2e9d7057cf3f8 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 7 Mar 2020 17:34:39 +0100 Subject: [PATCH 39/56] New Crowdin translations (#2485) * New translations strings.xml (Italian) * New translations strings.xml (Italian) * New translations strings.xml (Italian) * New translations strings.xml (French) * New translations strings.xml (Italian) * New translations objectives.xml (Italian) * New translations strings.xml (Italian) * New translations insight_alert_titles.xml (Italian) * New translations insight_exceptions.xml (Italian) * New translations strings.xml (Italian) --- app/src/main/res/values-fr-rFR/strings.xml | 4 ++-- .../values-it-rIT/insight_alert_titles.xml | 4 ++-- .../res/values-it-rIT/insight_exceptions.xml | 5 ++-- app/src/main/res/values-it-rIT/objectives.xml | 2 +- app/src/main/res/values-it-rIT/strings.xml | 24 +++++++++---------- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index 269ec85497..5dc5649fca 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -1425,10 +1425,10 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Âge invalide Poids invalide %1$s: ∑: %2$.2f Bol: %3$.2f Bas: %4$.2f]]> - %1$s: Bas: %2$02d%% Médian: %3$02d%% Haut: %4$02d%%]]> + %1$s: Bas: %2$02d%% Cible: %3$02d%% Haut: %4$02d%%]]> Moyenne DTI - TIR + Cible Gly Moniteur d\'activité Voulez-vous réinitialiser les stats d\'activité ? Statistiques diff --git a/app/src/main/res/values-it-rIT/insight_alert_titles.xml b/app/src/main/res/values-it-rIT/insight_alert_titles.xml index 0e3e09339f..123334b48d 100644 --- a/app/src/main/res/values-it-rIT/insight_alert_titles.xml +++ b/app/src/main/res/values-it-rIT/insight_alert_titles.xml @@ -9,8 +9,8 @@ Batteria quasi scarica Ora/data non valida Fine della garanzia - TBR annullato - Bolo annullato + TBR cancellato + Bolo cancellato Avviso di prestito Cartuccia non inserita Cartuccia vuota diff --git a/app/src/main/res/values-it-rIT/insight_exceptions.xml b/app/src/main/res/values-it-rIT/insight_exceptions.xml index fa33f5f7f2..fc68ba559f 100644 --- a/app/src/main/res/values-it-rIT/insight_exceptions.xml +++ b/app/src/main/res/values-it-rIT/insight_exceptions.xml @@ -1,5 +1,4 @@ - Connessione fallita Connessione persa @@ -7,9 +6,9 @@ Creazione socket fallita Timeout Numero massimo tipo di bolo già in esecuzione - Nessun TBR attivo da annullare + Nessun TBR attivo da cancellare Nessun TBR attivo da modificare - Nessun bolo da annullare + Nessun bolo da cancellare Micro già in questo stato Modalità di esecuzione non consentita diff --git a/app/src/main/res/values-it-rIT/objectives.xml b/app/src/main/res/values-it-rIT/objectives.xml index b34fde69ad..d8026431c0 100644 --- a/app/src/main/res/values-it-rIT/objectives.xml +++ b/app/src/main/res/values-it-rIT/objectives.xml @@ -24,7 +24,7 @@ Glicemia disponibile in NS Stato micro disponibile in NS Attivazioni manuali - Compiuto: %1$s + Completato: %1$s Impara a controllare AndroidAPS Esegui varie azioni in AndroidAPS Imposta il profilo \"90%\" per 10 min (premi a lungo sul nome profilo nella sezione Panoramica) diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 1d1fdc86ed..191ec45424 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -119,7 +119,7 @@ Trattamenti Quale plugin dovrebbe essere utilizzato per la gestione del trattamento? Profilo - Quale profilo dovrebbe usare AndroidAPS? + Quale profilo AndroidAPS dovrebbe usare? APS Quale algoritmo APS dovrebbe apportare aggiustamenti terapeutici? Generale @@ -247,7 +247,7 @@ OK Percentuale Assoluto - Cancellare basale temporanea + Cancella basale temporanea Comunicazioni SMS In attesa del risultato Numeri di telefono consentiti @@ -343,8 +343,8 @@ Per stoppare il bolo esteso rispondi col codice %1$s Basale temporanea cancellata Bolo esteso cancellato - Cancellazione basale temporanea fallita - Cancellazione bolo esteso fallita + Basale temporanea: cancellazione fallita + Bolo esteso: cancellazione fallita Comando sconosciuto o risposta errata Calcolatore Rapido Impostazioni Calcolatore Rapido @@ -638,8 +638,8 @@ Abilita SMB Utilizza Super Micro Boli al posto della basale temporanea per un\'azione più veloce Rilevazione dei pasti Non Annunciati - Momento picco Curva IOB - Momento del picco [min] + Tempo picco Curva IOB + Tempo del picco [min] Free-Peak Oref Rapid-Acting Oref Ultra-Rapid Oref @@ -771,7 +771,7 @@ Normale Necessario aggiornare orologio micro Attenzione - Avviso TBR CANCELLATO confermato + Avviso TBR CANCELLATO: confermato Il micro potrebbe non essere raggiungibile. Nessun bolo erogato Erogazione bolo fallita. Sembra che nessun bolo sia stato erogato. Per sicurezza, controlla il micro per evitare un doppio bolo e se è tutto ok, erogalo di nuovo. Come protezione da eventuali \"bug\", i boli non vengono ripetuti automaticamente. Solo la quantità di %1$.2f U del bolo richiesto di %2$.2f U è stata erogata a causa di un errore. Controlla il micro per verificare quanto accaduto e intraprendi le azioni necessarie. @@ -890,7 +890,7 @@ Micro in pausa Max tempo assorbimento pasto [h] Tempo entro il quale ogni pasto si considera assorbito. Eventuali carboidrati rimanenti verranno tagliati fuori. - Offset + Tempo Finestre tratt.nto: mostra campo note Avanti Indietro @@ -1161,10 +1161,10 @@ vincolo di archiviazione interna Libera almeno %1$d MB dalla memoria interna! Loop disabilitato! Formato errato - Codice errato. Comando annullato. + Codice errato. Comando cancellato. Non configurato Cambio profilo creato - Tempo di ripetizione + Tempo ricorrente Ogni Mai %1$dmin @@ -1395,8 +1395,8 @@ %1$dg On Off - Cancella completato - Cancella avviato + Cancella completamento + Cancella avvio Rilevazione tempo Vuoi resettare l\'avvio dell\'obiettivo? Potresti perdere i tuoi progressi. Nessun micro selezionato From 07aa6f20394d1f8493b7f75020c6b22fc7ed2165 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 7 Mar 2020 20:18:52 +0100 Subject: [PATCH 40/56] fix LocalProfile upload --- .../androidaps/plugins/general/nsclient/NSUpload.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java index 0bc15d1d45..ab6cae3e71 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java @@ -396,7 +396,7 @@ public class NSUpload { public static void uploadProfileStore(JSONObject profileStore) { if (SP.getBoolean(R.string.key_ns_uploadlocalprofile, false)) { - UploadQueue.add(new DbRequest("dbAdd", "profile", String.valueOf(profileStore))); + UploadQueue.add(new DbRequest("dbAdd", "profile", profileStore)); } } From 14bda9cf719770cdd3d638475190482254bfd0a6 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 7 Mar 2020 20:37:08 +0100 Subject: [PATCH 41/56] hide overview_accepttempbutton by default --- app/src/main/res/layout/overview_fragment.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/overview_fragment.xml b/app/src/main/res/layout/overview_fragment.xml index 467c8c171a..35ddd5eed4 100644 --- a/app/src/main/res/layout/overview_fragment.xml +++ b/app/src/main/res/layout/overview_fragment.xml @@ -477,7 +477,8 @@ app:layout_constraintBottom_toTopOf="@id/overview_buttons_layout" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/overview_toppart_scrollbar" /> + app:layout_constraintTop_toBottomOf="@id/overview_toppart_scrollbar" + android:visibility="gone"/> Date: Sat, 7 Mar 2020 20:50:49 +0100 Subject: [PATCH 42/56] scrollable buttons in landscape mode --- .../general/overview/OverviewFragment.java | 4 +- .../layout/overview_fragment_landscape.xml | 584 ++++++++++++++++++ 2 files changed, 586 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/layout/overview_fragment_landscape.xml diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java index 0976755f06..a00317eff3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java @@ -221,8 +221,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } else if (Config.NSCLIENT) { view = inflater.inflate(R.layout.overview_fragment_nsclient, container, false); shorttextmode = true; - } else if (smallHeight || landscape) { // now testing the same layout for small displays as well - view = inflater.inflate(R.layout.overview_fragment, container, false); + } else if (smallHeight || landscape) { + view = inflater.inflate(R.layout.overview_fragment_landscape, container, false); } else { view = inflater.inflate(R.layout.overview_fragment, container, false); } diff --git a/app/src/main/res/layout/overview_fragment_landscape.xml b/app/src/main/res/layout/overview_fragment_landscape.xml new file mode 100644 index 0000000000..edaa1df7a5 --- /dev/null +++ b/app/src/main/res/layout/overview_fragment_landscape.xml @@ -0,0 +1,584 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a53f173751d06b446dd581202abb02eedfa15869 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 8 Mar 2020 20:49:29 +0100 Subject: [PATCH 43/56] fix some warnings --- .../nightscout/androidaps/activities/SurveyActivity.kt | 2 +- .../general/automation/dialogs/EditActionDialog.kt | 8 ++++---- .../java/info/nightscout/androidaps/utils/OKDialog.kt | 2 -- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/SurveyActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/SurveyActivity.kt index bf07eda9af..d72e43441e 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/SurveyActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/SurveyActivity.kt @@ -84,7 +84,7 @@ class SurveyActivity : NoSplashAppCompatActivity() { .addOnCompleteListener(this) { task -> if (task.isSuccessful) { log.debug("signInAnonymously:success") - val user = auth.currentUser // TODO: do we need this, seems unused? + // val user = auth.currentUser // TODO: do we need this, seems unused? val database = FirebaseDatabase.getInstance().reference database.child("survey").child(r.id).setValue(r) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditActionDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditActionDialog.kt index e738b7f94c..63a053f29f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditActionDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditActionDialog.kt @@ -44,11 +44,11 @@ class EditActionDialog : DialogFragmentWithDate() { return true } - override fun onSaveInstanceState(bundle: Bundle) { - super.onSaveInstanceState(bundle) + override fun onSaveInstanceState(savedInstanceState: Bundle) { + super.onSaveInstanceState(savedInstanceState) action?.let { - bundle.putInt("actionPosition", actionPosition) - bundle.putString("action", it.toJSON()) + savedInstanceState.putInt("actionPosition", actionPosition) + savedInstanceState.putString("action", it.toJSON()) } } } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.kt b/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.kt index 1d22c380ca..830053bef0 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.kt @@ -62,13 +62,11 @@ object OKDialog { } @JvmStatic - @JvmOverloads fun showConfirmation(activity: Activity, message: String, ok: Runnable?) { showConfirmation(activity, MainApp.gs(R.string.confirmation), message, ok, null) } @JvmStatic - @JvmOverloads fun showConfirmation(activity: Activity, message: Spanned, ok: Runnable?) { showConfirmation(activity, MainApp.gs(R.string.confirmation), message, ok, null) } From 7d9c1f8af9b60c40e4713fd439d6fdc5eeb00d89 Mon Sep 17 00:00:00 2001 From: TebbeUbben Date: Mon, 9 Mar 2020 23:07:55 +0100 Subject: [PATCH 44/56] Use "Display time-sensitive notifications" for Insight alerts --- app/src/main/AndroidManifest.xml | 3 + .../pump/insight/InsightAlertService.java | 187 ++++++++++++------ .../pump/insight/LocalInsightPlugin.java | 15 ++ .../activities/InsightAlertActivity.java | 175 ++-------------- .../pump/insight/descriptors/Alert.java | 20 ++ .../plugins/pump/insight/utils/AlertUtils.kt | 107 ++++++++++ app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/styles.xml | 4 +- 8 files changed, 286 insertions(+), 226 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/utils/AlertUtils.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b571e247c2..6318d88e46 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,6 +23,7 @@ + @@ -264,6 +265,8 @@ alertLiveData = new MutableLiveData<>(); private Thread thread; - private InsightAlertActivity alertActivity; - private Ringtone ringtone; private Vibrator vibrator; private boolean vibrating; private InsightConnectionService connectionService; @@ -65,27 +68,6 @@ public class InsightAlertService extends Service implements InsightConnectionSer } }; - private void retrieveRingtone() { - Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); - ringtone = RingtoneManager.getRingtone(this, uri); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - ringtone.setAudioAttributes(new AudioAttributes.Builder() - .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) - .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN) - .setLegacyStreamType(AudioManager.STREAM_RING).build()); - } else ringtone.setStreamType(AudioManager.STREAM_RING); - } - - public Alert getAlert() { - synchronized ($alertLock) { - return alert; - } - } - - public void setAlertActivity(InsightAlertActivity alertActivity) { - this.alertActivity = alertActivity; - } - public void ignore(AlertType alertType) { synchronized ($alertLock) { if (alertType == null) { @@ -98,6 +80,10 @@ public class InsightAlertService extends Service implements InsightConnectionSer } } + public MutableLiveData getAlertLiveData() { + return alertLiveData; + } + @Nullable @Override public IBinder onBind(Intent intent) { @@ -108,6 +94,7 @@ public class InsightAlertService extends Service implements InsightConnectionSer public void onCreate() { vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); bindService(new Intent(this, InsightConnectionService.class), serviceConnection, BIND_AUTO_CREATE); + alertLiveData.setValue(null); } @Override @@ -118,6 +105,12 @@ public class InsightAlertService extends Service implements InsightConnectionSer @Override public int onStartCommand(Intent intent, int flags, int startId) { + if ("mute".equals(intent.getStringExtra("command"))) { + mute(); + } else if ("confirm".equals(intent.getStringExtra("command"))) { + dismissNotification(); + confirm(); + } return START_STICKY; } @@ -127,25 +120,47 @@ public class InsightAlertService extends Service implements InsightConnectionSer thread = new Thread(this::queryActiveAlert); thread.start(); - } else if (thread != null) thread.interrupt(); + } else { + dismissNotification(); + if (thread != null) thread.interrupt(); + } } private void queryActiveAlert() { while (!Thread.currentThread().isInterrupted()) { try { Alert alert = connectionService.requestMessage(new GetActiveAlertMessage()).await().getAlert(); - if (Thread.currentThread().isInterrupted()) { - connectionService.withdrawConnectionRequest(thread); - break; - } synchronized ($alertLock) { - if ((this.alert == null && alert != null) + if (alert == null || (alert.getAlertType() == ignoreType && System.currentTimeMillis() - ignoreTimestamp < 10000)) { + if (connectionRequested) { + connectionService.withdrawConnectionRequest(this); + connectionRequested = false; + } + this.alertLiveData.postValue(null); + this.alert = null; + dismissNotification(); + stopAlerting(); + } else if (!alert.equals(this.alert)) { + if (!connectionRequested) { + connectionService.requestConnection(this); + connectionRequested = true; + } + showNotification(alert); + this.alertLiveData.postValue(alert); + this.alert = alert; + if (alert.getAlertStatus() == AlertStatus.SNOOZED) stopAlerting(); + else alert(); + } + /*if ((this.alert == null && alert != null) || (this.alert != null && alert == null) || (this.alert != null && alert != null && !this.alert.equals(alert))) { if (this.alert != null && (alert == null || this.alert.getAlertId() != alert.getAlertId())) stopAlerting(); this.alert = alert; - if (alertActivity != null && alert != null) - new Handler(Looper.getMainLooper()).post(() -> alertActivity.update(alert)); + if (alert != null) + new Handler(Looper.getMainLooper()).post(() -> { + //showNotification(alert); + //alertActivity.update(alert); + }); } if (alert == null) { stopAlerting(); @@ -153,8 +168,10 @@ public class InsightAlertService extends Service implements InsightConnectionSer connectionService.withdrawConnectionRequest(this); connectionRequested = false; } - if (alertActivity != null) - new Handler(Looper.getMainLooper()).post(() -> alertActivity.finish()); + new Handler(Looper.getMainLooper()).post(() -> { + //dismissNotification(); + //alertActivity.finish(); + }); } else if (!(alert.getAlertType() == ignoreType && System.currentTimeMillis() - ignoreTimestamp < 10000)) { if (alert.getAlertStatus() == AlertStatus.ACTIVE) alert(); else stopAlerting(); @@ -162,12 +179,12 @@ public class InsightAlertService extends Service implements InsightConnectionSer connectionService.requestConnection(this); connectionRequested = true; } - if (alertActivity == null) { + /*if (alertActivity == null) { Intent intent = new Intent(InsightAlertService.this, InsightAlertActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); new Handler(Looper.getMainLooper()).post(() -> startActivity(intent)); - } - } + }*/ + //} } } catch (InterruptedException ignored) { connectionService.withdrawConnectionRequest(thread); @@ -189,21 +206,18 @@ public class InsightAlertService extends Service implements InsightConnectionSer connectionService.withdrawConnectionRequest(thread); connectionRequested = false; } - if (alertActivity != null) - new Handler(Looper.getMainLooper()).post(() -> alertActivity.finish()); stopAlerting(); + alertLiveData.postValue(null); + this.alert = null; + dismissNotification(); thread = null; } private void alert() { if (!vibrating) { - vibrator.vibrate(new long[] {0, 1000, 1000}, 0); + vibrator.vibrate(new long[]{0, 1000, 1000}, 0); vibrating = true; } - if (ringtone == null || !ringtone.isPlaying()) { - retrieveRingtone(); - ringtone.play(); - } } private void stopAlerting() { @@ -211,15 +225,21 @@ public class InsightAlertService extends Service implements InsightConnectionSer vibrator.cancel(); vibrating = false; } - if (ringtone != null && ringtone.isPlaying()) ringtone.stop(); } public void mute() { new Thread(() -> { try { - SnoozeAlertMessage snoozeAlertMessage = new SnoozeAlertMessage(); - snoozeAlertMessage.setAlertID(alert.getAlertId()); - connectionService.requestMessage(snoozeAlertMessage).await(); + synchronized ($alertLock) { + if (alert == null) return; + alert.setAlertStatus(AlertStatus.SNOOZED); + alertLiveData.postValue(alert); + stopAlerting(); + showNotification(alert); + SnoozeAlertMessage snoozeAlertMessage = new SnoozeAlertMessage(); + snoozeAlertMessage.setAlertID(alertLiveData.getValue().getAlertId()); + connectionService.requestMessage(snoozeAlertMessage).await(); + } } catch (AppLayerErrorException e) { log.info("Exception while muting alert: " + e.getClass().getCanonicalName() + " (" + e.getErrorCode() + ")"); ExceptionTranslator.makeToast(InsightAlertService.this, e); @@ -236,9 +256,16 @@ public class InsightAlertService extends Service implements InsightConnectionSer public void confirm() { new Thread(() -> { try { - ConfirmAlertMessage confirmAlertMessage = new ConfirmAlertMessage(); - confirmAlertMessage.setAlertID(alert.getAlertId()); - connectionService.requestMessage(confirmAlertMessage).await(); + synchronized ($alertLock) { + if (alert == null) return; + stopAlerting(); + alertLiveData.postValue(null); + dismissNotification(); + ConfirmAlertMessage confirmAlertMessage = new ConfirmAlertMessage(); + confirmAlertMessage.setAlertID(alertLiveData.getValue().getAlertId()); + connectionService.requestMessage(confirmAlertMessage).await(); + this.alert = null; + } } catch (AppLayerErrorException e) { log.info("Exception while confirming alert: " + e.getClass().getCanonicalName() + " (" + e.getErrorCode() + ")"); ExceptionTranslator.makeToast(InsightAlertService.this, e); @@ -252,6 +279,48 @@ public class InsightAlertService extends Service implements InsightConnectionSer }).start(); } + private void showNotification(Alert alert) { + NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, LocalInsightPlugin.ALERT_CHANNEL_ID); + + notificationBuilder.setPriority(NotificationCompat.PRIORITY_MAX); + notificationBuilder.setCategory(NotificationCompat.CATEGORY_ALARM); + notificationBuilder.setVibrate(new long[0]); + notificationBuilder.setShowWhen(false); + notificationBuilder.setOngoing(true); + notificationBuilder.setOnlyAlertOnce(true); + notificationBuilder.setAutoCancel(false); + notificationBuilder.setSmallIcon(AlertUtilsKt.getAlertIcon(alert.getAlertCategory())); + + notificationBuilder.setContentTitle(AlertUtilsKt.getAlertCode(alert.getAlertType()) + " – " + AlertUtilsKt.getAlertTitle(alert.getAlertType())); + String description = AlertUtilsKt.getAlertDescription(alert); + if (description != null) + notificationBuilder.setContentText(Html.fromHtml(description).toString()); + + Intent fullScreenIntent = new Intent(this, InsightAlertActivity.class); + PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT); + notificationBuilder.setFullScreenIntent(fullScreenPendingIntent, true); + + switch (alert.getAlertStatus()) { + case ACTIVE: + Intent muteIntent = new Intent(this, InsightAlertService.class).putExtra("command", "mute"); + PendingIntent mutePendingIntent = PendingIntent.getService(this, 1, muteIntent, PendingIntent.FLAG_UPDATE_CURRENT); + notificationBuilder.addAction(0, MainApp.gs(R.string.mute_alert), mutePendingIntent); + case SNOOZED: + Intent confirmIntent = new Intent(this, InsightAlertService.class).putExtra("command", "confirm"); + PendingIntent confirmPendingIntent = PendingIntent.getService(this, 2, confirmIntent, PendingIntent.FLAG_UPDATE_CURRENT); + notificationBuilder.addAction(0, MainApp.gs(R.string.confirm), confirmPendingIntent); + } + + Notification notification = notificationBuilder.build(); + NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, notification); + startForeground(NOTIFICATION_ID, notification); + } + + private void dismissNotification() { + NotificationManagerCompat.from(this).cancel(NOTIFICATION_ID); + stopForeground(true); + } + public class LocalBinder extends Binder { public InsightAlertService getService() { return InsightAlertService.this; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java index 2197b48577..66ee0bed5a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java @@ -1,9 +1,12 @@ package info.nightscout.androidaps.plugins.pump.insight; +import android.app.NotificationChannel; +import android.app.NotificationManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -132,6 +135,8 @@ import info.nightscout.androidaps.utils.SP; public class LocalInsightPlugin extends PluginBase implements PumpInterface, ConstraintsInterface, InsightConnectionService.StateCallback { + public static final String ALERT_CHANNEL_ID = "AndroidAPS-InsightAlert"; + private static LocalInsightPlugin instance = null; private Logger log = LoggerFactory.getLogger(L.PUMP); @@ -245,6 +250,15 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con super.onStart(); MainApp.instance().bindService(new Intent(MainApp.instance(), InsightConnectionService.class), serviceConnection, Context.BIND_AUTO_CREATE); MainApp.instance().bindService(new Intent(MainApp.instance(), InsightAlertService.class), serviceConnection, Context.BIND_AUTO_CREATE); + createNotificationChannel(); + } + + private void createNotificationChannel() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationManager notificationManager = (NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE); + NotificationChannel channel = new NotificationChannel(ALERT_CHANNEL_ID, MainApp.gs(R.string.insight_alert_notification_channel), NotificationManager.IMPORTANCE_HIGH); + notificationManager.createNotificationChannel(channel); + } } @Override @@ -647,6 +661,7 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con cancelBolusMessage.setBolusID(bolusID); connectionService.requestMessage(cancelBolusMessage).await(); bolusCancelled = true; + alertService.ignore(null); } confirmAlert(AlertType.WARNING_38); } catch (AppLayerErrorException e) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/activities/InsightAlertActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/activities/InsightAlertActivity.java index 77be3ab03a..8ebd05801b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/activities/InsightAlertActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/activities/InsightAlertActivity.java @@ -12,19 +12,18 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; +import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; -import java.text.DecimalFormat; - import info.nightscout.androidaps.R; import info.nightscout.androidaps.activities.NoSplashAppCompatActivity; import info.nightscout.androidaps.plugins.pump.insight.InsightAlertService; import info.nightscout.androidaps.plugins.pump.insight.descriptors.Alert; import info.nightscout.androidaps.plugins.pump.insight.descriptors.AlertStatus; +import info.nightscout.androidaps.plugins.pump.insight.utils.AlertUtilsKt; -public class InsightAlertActivity extends NoSplashAppCompatActivity { +public class InsightAlertActivity extends AppCompatActivity { - private Alert alert; private InsightAlertService alertService; private ImageView icon; @@ -38,10 +37,10 @@ public class InsightAlertActivity extends NoSplashAppCompatActivity { @Override public void onServiceConnected(ComponentName name, IBinder binder) { alertService = ((InsightAlertService.LocalBinder) binder).getService(); - alertService.setAlertActivity(InsightAlertActivity.this); - alert = alertService.getAlert(); - if (alert == null) finish(); - else update(alert); + alertService.getAlertLiveData().observe(InsightAlertActivity.this, alert -> { + if (alert == null) finish(); + else update(alert); + }); } @Override @@ -70,174 +69,22 @@ public class InsightAlertActivity extends NoSplashAppCompatActivity { | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); - WindowManager.LayoutParams layoutParams = getWindow().getAttributes(); - layoutParams.screenBrightness = 1.0F; - getWindow().setAttributes(layoutParams); } @Override protected void onDestroy() { - alertService.setAlertActivity(null); unbindService(serviceConnection); super.onDestroy(); } public void update(Alert alert) { - this.alert = alert; mute.setEnabled(true); mute.setVisibility(alert.getAlertStatus() == AlertStatus.SNOOZED ? View.GONE : View.VISIBLE); confirm.setEnabled(true); - int icon = 0; - int code = 0; - int title = 0; - String description = null; - switch (alert.getAlertCategory()) { - case ERROR: - icon = R.drawable.ic_error; - break; - case MAINTENANCE: - icon = R.drawable.ic_maintenance; - break; - case WARNING: - icon = R.drawable.ic_warning; - break; - case REMINDER: - icon = R.drawable.ic_reminder; - break; - } - DecimalFormat decimalFormat = new DecimalFormat("##0.00"); - int hours = alert.getTBRDuration() / 60; - int minutes = alert.getTBRDuration() - hours * 60; - switch (alert.getAlertType()) { - case REMINDER_01: - code = R.string.alert_r1_code; - title = R.string.alert_r1_title; - break; - case REMINDER_02: - code = R.string.alert_r2_code; - title = R.string.alert_r2_title; - break; - case REMINDER_03: - code = R.string.alert_r3_code; - title = R.string.alert_r3_title; - break; - case REMINDER_04: - code = R.string.alert_r4_code; - title = R.string.alert_r4_title; - break; - case REMINDER_07: - code = R.string.alert_r7_code; - title = R.string.alert_r7_title; - description = getString(R.string.alert_r7_description, alert.getTBRAmount(), new DecimalFormat("#0").format(hours) + ":" + new DecimalFormat("00").format(minutes)); - break; - case WARNING_31: - code = R.string.alert_w31_code; - title = R.string.alert_w31_title; - description = getString(R.string.alert_w31_description, decimalFormat.format(alert.getCartridgeAmount())); - break; - case WARNING_32: - code = R.string.alert_w32_code; - title = R.string.alert_w32_title; - description = getString(R.string.alert_w32_description); - break; - case WARNING_33: - code = R.string.alert_w33_code; - title = R.string.alert_w33_title; - description = getString(R.string.alert_w33_description); - break; - case WARNING_34: - code = R.string.alert_w34_code; - title = R.string.alert_w34_title; - description = getString(R.string.alert_w34_description); - break; - case WARNING_36: - code = R.string.alert_w36_code; - title = R.string.alert_w36_title; - description = getString(R.string.alert_w36_description, alert.getTBRAmount(), new DecimalFormat("#0").format(hours) + ":" + new DecimalFormat("00").format(minutes)); - break; - case WARNING_38: - code = R.string.alert_w38_code; - title = R.string.alert_w38_title; - description = getString(R.string.alert_w38_description, decimalFormat.format(alert.getProgrammedBolusAmount()), decimalFormat.format(alert.getDeliveredBolusAmount())); - break; - case WARNING_39: - code = R.string.alert_w39_code; - title = R.string.alert_w39_title; - break; - case MAINTENANCE_20: - code = R.string.alert_m20_code; - title = R.string.alert_m20_title; - description = getString(R.string.alert_m20_description); - break; - case MAINTENANCE_21: - code = R.string.alert_m21_code; - title = R.string.alert_m21_title; - description = getString(R.string.alert_m21_description); - break; - case MAINTENANCE_22: - code = R.string.alert_m22_code; - title = R.string.alert_m22_title; - description = getString(R.string.alert_m22_description); - break; - case MAINTENANCE_23: - code = R.string.alert_m23_code; - title = R.string.alert_m23_title; - description = getString(R.string.alert_m23_description); - break; - case MAINTENANCE_24: - code = R.string.alert_m24_code; - title = R.string.alert_m24_title; - description = getString(R.string.alert_m24_description); - break; - case MAINTENANCE_25: - code = R.string.alert_m25_code; - title = R.string.alert_m25_title; - description = getString(R.string.alert_m25_description); - break; - case MAINTENANCE_26: - code = R.string.alert_m26_code; - title = R.string.alert_m26_title; - description = getString(R.string.alert_m26_description); - break; - case MAINTENANCE_27: - code = R.string.alert_m27_code; - title = R.string.alert_m27_title; - description = getString(R.string.alert_m27_description); - break; - case MAINTENANCE_28: - code = R.string.alert_m28_code; - title = R.string.alert_m28_title; - description = getString(R.string.alert_m28_description); - break; - case MAINTENANCE_29: - code = R.string.alert_m29_code; - title = R.string.alert_m29_title; - description = getString(R.string.alert_m29_description); - break; - case MAINTENANCE_30: - code = R.string.alert_m30_code; - title = R.string.alert_m30_title; - description = getString(R.string.alert_m30_description); - break; - case ERROR_6: - code = R.string.alert_e6_code; - title = R.string.alert_e6_title; - description = getString(R.string.alert_e6_description); - break; - case ERROR_10: - code = R.string.alert_e10_code; - title = R.string.alert_e10_title; - description = getString(R.string.alert_e10_description); - break; - case ERROR_13: - code = R.string.alert_e13_code; - title = R.string.alert_e13_title; - description = getString(R.string.alert_e13_description); - break; - } - this.icon.setImageDrawable(ContextCompat.getDrawable(this, icon)); - this.errorCode.setText(code); - this.errorTitle.setText(title); + this.icon.setImageDrawable(ContextCompat.getDrawable(this, AlertUtilsKt.getAlertIcon(alert.getAlertCategory()))); + this.errorCode.setText(AlertUtilsKt.getAlertCode(alert.getAlertType())); + this.errorTitle.setText(AlertUtilsKt.getAlertTitle(alert.getAlertType())); + String description = AlertUtilsKt.getAlertDescription(alert); if (description == null) this.errorDescription.setVisibility(View.GONE); else { this.errorDescription.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/descriptors/Alert.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/descriptors/Alert.java index 8f6668c1ca..028fcb3b71 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/descriptors/Alert.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/descriptors/Alert.java @@ -83,4 +83,24 @@ public class Alert { public double getCartridgeAmount() { return cartridgeAmount; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Alert alert = (Alert) o; + + if (alertId != alert.alertId) return false; + if (tbrAmount != alert.tbrAmount) return false; + if (tbrDuration != alert.tbrDuration) return false; + if (Double.compare(alert.programmedBolusAmount, programmedBolusAmount) != 0) + return false; + if (Double.compare(alert.deliveredBolusAmount, deliveredBolusAmount) != 0) + return false; + if (Double.compare(alert.cartridgeAmount, cartridgeAmount) != 0) return false; + if (alertCategory != alert.alertCategory) return false; + if (alertType != alert.alertType) return false; + return alertStatus == alert.alertStatus; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/utils/AlertUtils.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/utils/AlertUtils.kt new file mode 100644 index 0000000000..7cafb950cc --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/utils/AlertUtils.kt @@ -0,0 +1,107 @@ +package info.nightscout.androidaps.plugins.pump.insight.utils + +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.plugins.pump.insight.descriptors.Alert +import info.nightscout.androidaps.plugins.pump.insight.descriptors.AlertCategory +import info.nightscout.androidaps.plugins.pump.insight.descriptors.AlertType +import java.text.DecimalFormat + +fun getAlertCode(alertType: AlertType) = MainApp.gs(when (alertType) { + AlertType.REMINDER_01 -> R.string.alert_r1_code + AlertType.REMINDER_02 -> R.string.alert_r2_code + AlertType.REMINDER_03 -> R.string.alert_r3_code + AlertType.REMINDER_04 -> R.string.alert_r4_code + AlertType.REMINDER_07 -> R.string.alert_r7_code + AlertType.WARNING_31 -> R.string.alert_w31_code + AlertType.WARNING_32 -> R.string.alert_w32_code + AlertType.WARNING_33 -> R.string.alert_w33_code + AlertType.WARNING_34 -> R.string.alert_w34_code + AlertType.WARNING_36 -> R.string.alert_w36_code + AlertType.WARNING_38 -> R.string.alert_w38_code + AlertType.WARNING_39 -> R.string.alert_w39_code + AlertType.MAINTENANCE_20 -> R.string.alert_m20_code + AlertType.MAINTENANCE_21 -> R.string.alert_m21_code + AlertType.MAINTENANCE_22 -> R.string.alert_m22_code + AlertType.MAINTENANCE_23 -> R.string.alert_m23_code + AlertType.MAINTENANCE_24 -> R.string.alert_m24_code + AlertType.MAINTENANCE_25 -> R.string.alert_m25_code + AlertType.MAINTENANCE_26 -> R.string.alert_m26_code + AlertType.MAINTENANCE_27 -> R.string.alert_m27_code + AlertType.MAINTENANCE_28 -> R.string.alert_m28_code + AlertType.MAINTENANCE_29 -> R.string.alert_m29_code + AlertType.MAINTENANCE_30 -> R.string.alert_m30_code + AlertType.ERROR_6 -> R.string.alert_e6_code + AlertType.ERROR_10 -> R.string.alert_e10_code + AlertType.ERROR_13 -> R.string.alert_e13_code +}) + +fun getAlertTitle(alertType: AlertType) = MainApp.gs(when (alertType) { + AlertType.REMINDER_01 -> R.string.alert_r1_title + AlertType.REMINDER_02 -> R.string.alert_r2_title + AlertType.REMINDER_03 -> R.string.alert_r3_title + AlertType.REMINDER_04 -> R.string.alert_r4_title + AlertType.REMINDER_07 -> R.string.alert_r7_title + AlertType.WARNING_31 -> R.string.alert_w31_title + AlertType.WARNING_32 -> R.string.alert_w32_title + AlertType.WARNING_33 -> R.string.alert_w33_title + AlertType.WARNING_34 -> R.string.alert_w34_title + AlertType.WARNING_36 -> R.string.alert_w36_title + AlertType.WARNING_38 -> R.string.alert_w38_title + AlertType.WARNING_39 -> R.string.alert_w39_title + AlertType.MAINTENANCE_20 -> R.string.alert_m20_title + AlertType.MAINTENANCE_21 -> R.string.alert_m21_title + AlertType.MAINTENANCE_22 -> R.string.alert_m22_title + AlertType.MAINTENANCE_23 -> R.string.alert_m23_title + AlertType.MAINTENANCE_24 -> R.string.alert_m24_title + AlertType.MAINTENANCE_25 -> R.string.alert_m25_title + AlertType.MAINTENANCE_26 -> R.string.alert_m26_title + AlertType.MAINTENANCE_27 -> R.string.alert_m27_title + AlertType.MAINTENANCE_28 -> R.string.alert_m28_title + AlertType.MAINTENANCE_29 -> R.string.alert_m29_title + AlertType.MAINTENANCE_30 -> R.string.alert_m30_title + AlertType.ERROR_6 -> R.string.alert_e6_title + AlertType.ERROR_10 -> R.string.alert_e10_title + AlertType.ERROR_13 -> R.string.alert_e13_title +}) + +fun getAlertDescription(alert: Alert): String? { + val decimalFormat = DecimalFormat("##0.00") + val hours = alert.tbrDuration / 60 + val minutes = alert.tbrDuration - hours * 60 + return when (alert.alertType!!) { + AlertType.REMINDER_01 -> null + AlertType.REMINDER_02 -> null + AlertType.REMINDER_03 -> null + AlertType.REMINDER_04 -> null + AlertType.REMINDER_07 -> MainApp.gs(R.string.alert_r7_description, alert.tbrAmount, DecimalFormat("#0").format(hours.toLong()) + ":" + DecimalFormat("00").format(minutes.toLong())) + AlertType.WARNING_31 -> MainApp.gs(R.string.alert_w31_description, decimalFormat.format(alert.cartridgeAmount)) + AlertType.WARNING_32 -> MainApp.gs(R.string.alert_w32_description) + AlertType.WARNING_33 -> MainApp.gs(R.string.alert_w33_description) + AlertType.WARNING_34 -> MainApp.gs(R.string.alert_w34_description) + AlertType.WARNING_36 -> MainApp.gs(R.string.alert_w36_description, alert.tbrAmount, DecimalFormat("#0").format(hours.toLong()) + ":" + DecimalFormat("00").format(minutes.toLong())) + AlertType.WARNING_38 -> MainApp.gs(R.string.alert_w38_description, decimalFormat.format(alert.programmedBolusAmount), decimalFormat.format(alert.deliveredBolusAmount)) + AlertType.WARNING_39 -> null + AlertType.MAINTENANCE_20 -> MainApp.gs(R.string.alert_m20_description) + AlertType.MAINTENANCE_21 -> MainApp.gs(R.string.alert_m21_description) + AlertType.MAINTENANCE_22 -> MainApp.gs(R.string.alert_m22_description) + AlertType.MAINTENANCE_23 -> MainApp.gs(R.string.alert_m23_description) + AlertType.MAINTENANCE_24 -> MainApp.gs(R.string.alert_m24_description) + AlertType.MAINTENANCE_25 -> MainApp.gs(R.string.alert_m25_description) + AlertType.MAINTENANCE_26 -> MainApp.gs(R.string.alert_m26_description) + AlertType.MAINTENANCE_27 -> MainApp.gs(R.string.alert_m27_description) + AlertType.MAINTENANCE_28 -> MainApp.gs(R.string.alert_m28_description) + AlertType.MAINTENANCE_29 -> MainApp.gs(R.string.alert_m29_description) + AlertType.MAINTENANCE_30 -> MainApp.gs(R.string.alert_m30_description) + AlertType.ERROR_6 -> MainApp.gs(R.string.alert_e6_description) + AlertType.ERROR_10 -> MainApp.gs(R.string.alert_e10_description) + AlertType.ERROR_13 -> MainApp.gs(R.string.alert_e13_description) + } +} + +fun getAlertIcon(alertCategory: AlertCategory) = when (alertCategory) { + AlertCategory.ERROR -> R.drawable.ic_error + AlertCategory.MAINTENANCE -> R.drawable.ic_maintenance + AlertCategory.WARNING -> R.drawable.ic_warning + AlertCategory.REMINDER -> R.drawable.ic_reminder +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2e06c2a027..a4c79cb63b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1698,5 +1698,6 @@ SMB execution time Temp basal request time Temp basal execution time + Insight Pump Alerts
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d2cacff3b7..d78df37ac4 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -27,12 +27,10 @@ @android:style/Animation -