Merge pull request #12 from MilosKozak/dev

latest dev
This commit is contained in:
Roumen Georgiev 2018-04-11 13:23:15 +03:00 committed by GitHub
commit 4a293373ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
119 changed files with 2111 additions and 1650 deletions

View file

@ -18,7 +18,17 @@ before_install:
script:
# Unit Test
- ./gradlew -Pcoverage test jacocoTestReport
- ./gradlew -Pcoverage testFullDebugUnitTest jacocoTestFullDebugUnitTestReport
after_success:
- bash <(curl -s https://codecov.io/bash)
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- $HOME/.android/build-cache

View file

@ -15,8 +15,7 @@ apply plugin: "jacoco-android"
apply plugin: 'com.jakewharton.butterknife'
ext {
supportLibraryVersion = "27.0.2"
sdkBuildVersion = "27.0.3"
supportLibraryVersion = "27.1.0"
ormLiteVersion = "4.46"
powermockVersion = "1.7.3"
dexmakerVersion = "1.2"
@ -57,15 +56,14 @@ tasks.matching {it instanceof Test}.all {
android {
compileSdkVersion 27
buildToolsVersion "${sdkBuildVersion}"
defaultConfig {
applicationId "info.nightscout.androidaps"
minSdkVersion 21
targetSdkVersion 27
targetSdkVersion 25
multiDexEnabled true
versionCode 1500
version "1.60c-dev"
version "1.60d-dev"
buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", generateGitBuild()
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
@ -78,7 +76,7 @@ android {
// TODO remove once wear dependency com.google.android.gms:play-services-wearable:7.3.0
// has been upgraded (requiring significant code changes), which currently fails release
// build with a deprecation warning
// abortOnError false
abortOnError false
// (disabled entirely to avoid reports on the error, which would still be displayed
// and it's easy to overlook that it's ignored)
checkReleaseBuilds false
@ -183,7 +181,7 @@ dependencies {
implementation("com.crashlytics.sdk.android:answers:1.3.12@aar") {
transitive = true;
}
libs 'MilosKozak:danars-support-lib:master@zip'
libs "MilosKozak:danars-support-lib:master@zip"
implementation "com.android.support:appcompat-v7:${supportLibraryVersion}"
implementation "com.android.support:support-v4:${supportLibraryVersion}"

Binary file not shown.

View file

@ -32,7 +32,6 @@ public class Config {
public static final boolean logPumpComm = true;
public static final boolean logPrefsChange = true;
public static final boolean logConfigBuilder = true;
public static final boolean logConstraintsChanges = true;
public static final boolean logNSUpload = true;
public static final boolean logPumpActions = true;
public static final boolean logCongigBuilderActions = true;
@ -43,6 +42,4 @@ public class Config {
public static final boolean logDanaBTComm = true;
public static boolean logDanaMessageDetail = true;
public static final boolean logDanaSerialEngine = true;
public static final boolean enableComboBetaFeatures = false;
}

View file

@ -41,10 +41,10 @@ public class Constants {
// Temp targets
public static final int defaultActivityTTDuration = 90; // min
public static final double defaultActivityTTmgdl = 90d;
public static final double defaultActivityTTmgdl = 140d;
public static final double defaultActivityTTmmol = 8d;
public static final int defaultEatingSoonTTDuration = 45; // min
public static final double defaultEatingSoonTTmgdl = 140d;
public static final double defaultEatingSoonTTmgdl = 90d;
public static final double defaultEatingSoonTTmmol = 5d;
public static final int defaultHypoTTDuration = 30; // min
public static final double defaultHypoTTmgdl = 120d;

View file

@ -48,6 +48,7 @@ import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Food.FoodPlugin;
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.androidaps.tabs.SlidingTabLayout;
import info.nightscout.androidaps.tabs.TabPageAdapter;
import info.nightscout.utils.ImportExportPrefs;
@ -378,7 +379,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
MainApp.getDbHelper().resetDatabases();
// should be handled by Plugin-Interface and
// additional service interface and plugin registry
MainApp.getSpecificPlugin(FoodPlugin.class).getService().resetFood();
FoodPlugin.getPlugin().getService().resetFood();
TreatmentsPlugin.getPlugin().getService().resetTreatments();
}
})
.create()
@ -403,7 +405,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
else
builder.setIcon(R.mipmap.blueowl);
String message = "Build: " + BuildConfig.BUILDVERSION + "\n";
message += MainApp.sResources.getString(R.string.configbuilder_nightscoutversion_label) + " " + ConfigBuilderPlugin.nightscoutVersionName;
message += "Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + "\n";
message += getString(R.string.configbuilder_nightscoutversion_label) + " " + ConfigBuilderPlugin.nightscoutVersionName;
if (MainApp.engineeringMode)
message += "\n" + MainApp.gs(R.string.engineering_mode_enabled);
message += getString(R.string.about_link_urls);

View file

@ -212,11 +212,6 @@ public class MainApp extends Application {
startKeepAliveService();
}).start();
}
if (!isEngineeringModeOrRelease()) {
Notification n = new Notification(Notification.TOAST_ALARM, gs(R.string.closed_loop_disabled_on_dev_branch), Notification.NORMAL);
bus().post(new EventNewNotification(n));
}
}
private void registerLocalBroadcastReceiver() {

View file

@ -19,6 +19,7 @@ import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.events.EventNsFood;
import info.nightscout.androidaps.events.EventNsTreatment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus;
@ -40,6 +41,7 @@ import info.nightscout.androidaps.plugins.Source.SourceNSClientPlugin;
import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin;
import info.nightscout.androidaps.receivers.DataReceiver;
import info.nightscout.utils.BundleLogger;
import info.nightscout.utils.JsonHelper;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.SP;
@ -382,19 +384,18 @@ public class DataService extends IntentService {
if (intent.getAction().equals(Intents.ACTION_NEW_TREATMENT) || intent.getAction().equals(Intents.ACTION_CHANGED_TREATMENT)) {
try {
if (bundles.containsKey("treatment")) {
String trstring = bundles.getString("treatment");
handleAddChangeDataFromNS(trstring);
JSONObject json = new JSONObject(bundles.getString("treatment"));
handleTreatmentFromNS(json, intent);
}
if (bundles.containsKey("treatments")) {
String trstring = bundles.getString("treatments");
JSONArray jsonArray = new JSONArray(trstring);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject trJson = jsonArray.getJSONObject(i);
String trstr = trJson.toString();
handleAddChangeDataFromNS(trstr);
JSONObject json = jsonArray.getJSONObject(i);
handleTreatmentFromNS(json, intent);
}
}
} catch (Exception e) {
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
@ -403,21 +404,19 @@ public class DataService extends IntentService {
try {
if (bundles.containsKey("treatment")) {
String trstring = bundles.getString("treatment");
JSONObject trJson = new JSONObject(trstring);
String _id = trJson.getString("_id");
handleRemovedRecordFromNS(_id);
JSONObject json = new JSONObject(trstring);
handleTreatmentFromNS(json);
}
if (bundles.containsKey("treatments")) {
String trstring = bundles.getString("treatments");
JSONArray jsonArray = new JSONArray(trstring);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject trJson = jsonArray.getJSONObject(i);
String _id = trJson.getString("_id");
handleRemovedRecordFromNS(_id);
JSONObject json = jsonArray.getJSONObject(i);
handleTreatmentFromNS(json);
}
}
} catch (Exception e) {
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
@ -489,8 +488,12 @@ public class DataService extends IntentService {
}
}
private void handleRemovedRecordFromNS(String _id) {
MainApp.getDbHelper().deleteTreatmentById(_id);
private void handleTreatmentFromNS(JSONObject json) {
// new DB model
EventNsTreatment evtTreatment = new EventNsTreatment(EventNsTreatment.REMOVE, json);
MainApp.bus().post(evtTreatment);
// old DB model
String _id = JsonHelper.safeGetString(json, "_id");
MainApp.getDbHelper().deleteTempTargetById(_id);
MainApp.getDbHelper().deleteTempBasalById(_id);
MainApp.getDbHelper().deleteExtendedBolusById(_id);
@ -498,86 +501,53 @@ public class DataService extends IntentService {
MainApp.getDbHelper().deleteProfileSwitchById(_id);
}
private void handleAddChangeDataFromNS(String trstring) throws JSONException {
JSONObject trJson = new JSONObject(trstring);
handleDanaRHistoryRecords(trJson); // update record _id in history
handleAddChangeTempTargetRecord(trJson);
handleAddChangeTempBasalRecord(trJson);
handleAddChangeExtendedBolusRecord(trJson);
handleAddChangeCareportalEventRecord(trJson);
handleAddChangeTreatmentRecord(trJson);
handleAddChangeProfileSwitchRecord(trJson);
private void handleTreatmentFromNS(JSONObject json, Intent intent) throws JSONException {
// new DB model
int mode = Intents.ACTION_NEW_TREATMENT.equals(intent.getAction()) ? EventNsTreatment.ADD : EventNsTreatment.UPDATE;
double insulin = JsonHelper.safeGetDouble(json, "insulin");
double carbs = JsonHelper.safeGetDouble(json, "carbs");
String eventType = JsonHelper.safeGetString(json, "eventType");
if (insulin > 0 || carbs > 0) {
EventNsTreatment evtTreatment = new EventNsTreatment(mode, json);
MainApp.bus().post(evtTreatment);
} else if (json.has(DanaRNSHistorySync.DANARSIGNATURE)) {
// old DB model
MainApp.getDbHelper().updateDanaRHistoryRecordId(json);
} else if (eventType.equals(CareportalEvent.TEMPORARYTARGET)) {
MainApp.getDbHelper().createTemptargetFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.TEMPBASAL)) {
MainApp.getDbHelper().createTempBasalFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.COMBOBOLUS)) {
MainApp.getDbHelper().createExtendedBolusFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.PROFILESWITCH)) {
MainApp.getDbHelper().createProfileSwitchFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.SITECHANGE) ||
eventType.equals(CareportalEvent.INSULINCHANGE) ||
eventType.equals(CareportalEvent.SENSORCHANGE) ||
eventType.equals(CareportalEvent.BGCHECK) ||
eventType.equals(CareportalEvent.NOTE) ||
eventType.equals(CareportalEvent.NONE) ||
eventType.equals(CareportalEvent.ANNOUNCEMENT) ||
eventType.equals(CareportalEvent.QUESTION) ||
eventType.equals(CareportalEvent.EXERCISE) ||
eventType.equals(CareportalEvent.OPENAPSOFFLINE) ||
eventType.equals(CareportalEvent.PUMPBATTERYCHANGE)) {
MainApp.getDbHelper().createCareportalEventFromJsonIfNotExists(json);
}
public void handleDanaRHistoryRecords(JSONObject trJson) {
if (trJson.has(DanaRNSHistorySync.DANARSIGNATURE)) {
MainApp.getDbHelper().updateDanaRHistoryRecordId(trJson);
}
}
public void handleAddChangeTreatmentRecord(JSONObject trJson) throws JSONException {
if (trJson.has("insulin") || trJson.has("carbs")) {
MainApp.getDbHelper().createTreatmentFromJsonIfNotExists(trJson);
return;
}
}
public void handleAddChangeTempTargetRecord(JSONObject trJson) throws JSONException {
if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.TEMPORARYTARGET)) {
MainApp.getDbHelper().createTemptargetFromJsonIfNotExists(trJson);
}
}
public void handleAddChangeTempBasalRecord(JSONObject trJson) throws JSONException {
if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.TEMPBASAL)) {
MainApp.getDbHelper().createTempBasalFromJsonIfNotExists(trJson);
}
}
public void handleAddChangeExtendedBolusRecord(JSONObject trJson) throws JSONException {
if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.COMBOBOLUS)) {
MainApp.getDbHelper().createExtendedBolusFromJsonIfNotExists(trJson);
}
}
public void handleAddChangeCareportalEventRecord(JSONObject trJson) throws JSONException {
if (trJson.has("insulin") && trJson.getDouble("insulin") > 0)
return;
if (trJson.has("carbs") && trJson.getDouble("carbs") > 0)
return;
if (trJson.has("eventType") && (
trJson.getString("eventType").equals(CareportalEvent.SITECHANGE) ||
trJson.getString("eventType").equals(CareportalEvent.INSULINCHANGE) ||
trJson.getString("eventType").equals(CareportalEvent.SENSORCHANGE) ||
trJson.getString("eventType").equals(CareportalEvent.BGCHECK) ||
trJson.getString("eventType").equals(CareportalEvent.NOTE) ||
trJson.getString("eventType").equals(CareportalEvent.NONE) ||
trJson.getString("eventType").equals(CareportalEvent.ANNOUNCEMENT) ||
trJson.getString("eventType").equals(CareportalEvent.QUESTION) ||
trJson.getString("eventType").equals(CareportalEvent.EXERCISE) ||
trJson.getString("eventType").equals(CareportalEvent.OPENAPSOFFLINE) ||
trJson.getString("eventType").equals(CareportalEvent.PUMPBATTERYCHANGE)
)) {
MainApp.getDbHelper().createCareportalEventFromJsonIfNotExists(trJson);
}
if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.ANNOUNCEMENT)) {
long date = trJson.getLong("mills");
if (eventType.equals(CareportalEvent.ANNOUNCEMENT)) {
long date = JsonHelper.safeGetLong(json,"mills");
long now = System.currentTimeMillis();
if (date > now - 15 * 60 * 1000L && trJson.has("notes")
&& !(trJson.has("enteredBy") && trJson.getString("enteredBy").equals(SP.getString("careportal_enteredby", "AndroidAPS")))) {
Notification announcement = new Notification(Notification.NSANNOUNCEMENT, trJson.getString("notes"), Notification.ANNOUNCEMENT, 60);
String enteredBy = JsonHelper.safeGetString(json, "enteredBy", "");
String notes = JsonHelper.safeGetString(json, "notes", "");
if (date > now - 15 * 60 * 1000L && !notes.isEmpty()
&& !enteredBy.equals(SP.getString("careportal_enteredby", "AndroidAPS"))) {
Notification announcement = new Notification(Notification.NSANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60);
MainApp.bus().post(new EventNewNotification(announcement));
}
}
}
public void handleAddChangeProfileSwitchRecord(JSONObject trJson) throws JSONException {
if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.PROFILESWITCH)) {
MainApp.getDbHelper().createProfileSwitchFromJsonIfNotExists(trJson);
}
}
private void handleNewSMS(Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle == null) return;

View file

@ -129,6 +129,9 @@ public class TDDStatsActivity extends Activity {
}
totalBaseBasal.setText(TBB);
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().needsManualTDDLoad)
reloadButton.setVisibility(View.GONE);
// stats table
tl = (TableLayout) findViewById(R.id.main_table);
TableRow tr_head = new TableRow(this);
@ -436,7 +439,7 @@ public class TDDStatsActivity extends Activity {
TableLayout.LayoutParams.WRAP_CONTENT));
}
if (isOldData(historyList)) {
if (isOldData(historyList) && ConfigBuilderPlugin.getActivePump().getPumpDescription().needsManualTDDLoad) {
statsMessage.setVisibility(View.VISIBLE);
statsMessage.setText(getString(R.string.danar_stats_olddata_Message));

View file

@ -24,9 +24,6 @@ public class IobTotal {
// oref1
public long lastBolusTime;
public long lastTempDate;
public int lastTempDuration;
public double lastTempRate;
public IobTotal iobWithZeroTemp;
public double netInsulin = 0d; // for calculations from temp basals only
@ -76,9 +73,6 @@ public class IobTotal {
result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin;
result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin;
result.lastBolusTime = bolusIOB.lastBolusTime;
result.lastTempDate = basalIob.lastTempDate;
result.lastTempRate = basalIob.lastTempRate;
result.lastTempDuration = basalIob.lastTempDuration;
result.iobWithZeroTemp = basalIob.iobWithZeroTemp;
return result;
}

View file

@ -10,6 +10,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.utils.SP;
/**
* Created by mike on 12.10.2016.
@ -25,10 +26,7 @@ public class QuickWizard {
}
public void save() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putString("QuickWizard", storage.toString());
editor.apply();
SP.putString("QuickWizard", storage.toString());
}
public int size() {

View file

@ -98,6 +98,14 @@ public class CareportalEvent implements DataPointWithLabelInterface {
return diff.get(TimeUnit.DAYS) + " " + MainApp.sResources.getString(R.string.days) + " " + diff.get(TimeUnit.HOURS) + " " + MainApp.sResources.getString(R.string.hours);
}
public boolean isOlderThan(double hours) {
Map<TimeUnit, Long> diff = computeDiff(date, System.currentTimeMillis());
if(diff.get(TimeUnit.DAYS)*24 + diff.get(TimeUnit.HOURS) > hours)
return true;
else
return false;
}
public String log() {
return "CareportalEvent{" +
"date= " + date +
@ -259,4 +267,5 @@ public class CareportalEvent implements DataPointWithLabelInterface {
public int getSecondColor() {
return 0;
}
}

View file

@ -28,9 +28,7 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.events.EventCareportalEventChange;
@ -43,15 +41,10 @@ import info.nightscout.androidaps.events.EventReloadTempBasalData;
import info.nightscout.androidaps.events.EventReloadTreatmentData;
import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.events.EventTempTargetChange;
import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.PercentageSplitter;
import info.nightscout.utils.ToastUtils;
@ -72,7 +65,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public static final String DATABASE_TEMPORARYBASALS = "TemporaryBasals";
public static final String DATABASE_EXTENDEDBOLUSES = "ExtendedBoluses";
public static final String DATABASE_TEMPTARGETS = "TempTargets";
public static final String DATABASE_TREATMENTS = "Treatments";
public static final String DATABASE_DANARHISTORY = "DanaRHistory";
public static final String DATABASE_DBREQUESTS = "DBRequests";
public static final String DATABASE_CAREPORTALEVENTS = "CareportalEvents";
@ -81,14 +73,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
private static final int DATABASE_VERSION = 8;
private static Long earliestDataChange = null;
public static Long earliestDataChange = null;
private static final ScheduledExecutorService bgWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledBgPost = null;
private static final ScheduledExecutorService treatmentsWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledTratmentPost = null;
private static final ScheduledExecutorService tempBasalsWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledTemBasalsPost = null;
@ -118,7 +107,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
try {
log.info("onCreate");
TableUtils.createTableIfNotExists(connectionSource, TempTarget.class);
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
TableUtils.createTableIfNotExists(connectionSource, BgReading.class);
TableUtils.createTableIfNotExists(connectionSource, DanaRHistoryRecord.class);
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
@ -141,12 +129,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
if (oldVersion == 7 && newVersion == 8) {
log.debug("Upgrading database from v7 to v8");
TableUtils.dropTable(connectionSource, Treatment.class, true);
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
} else {
log.info(DatabaseHelper.class.getName(), "onUpgrade");
TableUtils.dropTable(connectionSource, TempTarget.class, true);
TableUtils.dropTable(connectionSource, Treatment.class, true);
TableUtils.dropTable(connectionSource, BgReading.class, true);
TableUtils.dropTable(connectionSource, DanaRHistoryRecord.class, true);
TableUtils.dropTable(connectionSource, DbRequest.class, true);
@ -178,40 +163,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
super.close();
}
public void cleanUpDatabases() {
// TODO: call it somewhere
log.debug("Before BgReadings size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_BGREADINGS));
getWritableDatabase().delete(DATABASE_BGREADINGS, "date" + " < '" + (System.currentTimeMillis() - Constants.hoursToKeepInDatabase * 60 * 60 * 1000L) + "'", null);
log.debug("After BgReadings size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_BGREADINGS));
log.debug("Before TempTargets size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TEMPTARGETS));
getWritableDatabase().delete(DATABASE_TEMPTARGETS, "date" + " < '" + (System.currentTimeMillis() - Constants.hoursToKeepInDatabase * 60 * 60 * 1000L) + "'", null);
log.debug("After TempTargets size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TEMPTARGETS));
log.debug("Before Treatments size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TREATMENTS));
getWritableDatabase().delete(DATABASE_TREATMENTS, "date" + " < '" + (System.currentTimeMillis() - Constants.hoursToKeepInDatabase * 60 * 60 * 1000L) + "'", null);
log.debug("After Treatments size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TREATMENTS));
log.debug("Before History size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_DANARHISTORY));
getWritableDatabase().delete(DATABASE_DANARHISTORY, "recordDate" + " < '" + (System.currentTimeMillis() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null);
log.debug("After History size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_DANARHISTORY));
log.debug("Before TemporaryBasals size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TEMPORARYBASALS));
getWritableDatabase().delete(DATABASE_TEMPORARYBASALS, "recordDate" + " < '" + (System.currentTimeMillis() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null);
log.debug("After TemporaryBasals size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TEMPORARYBASALS));
log.debug("Before ExtendedBoluses size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_EXTENDEDBOLUSES));
getWritableDatabase().delete(DATABASE_EXTENDEDBOLUSES, "recordDate" + " < '" + (System.currentTimeMillis() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null);
log.debug("After ExtendedBoluses size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_EXTENDEDBOLUSES));
log.debug("Before CareportalEvent size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_CAREPORTALEVENTS));
getWritableDatabase().delete(DATABASE_CAREPORTALEVENTS, "recordDate" + " < '" + (System.currentTimeMillis() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null);
log.debug("After CareportalEvent size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_CAREPORTALEVENTS));
log.debug("Before ProfileSwitch size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_PROFILESWITCHES));
getWritableDatabase().delete(DATABASE_PROFILESWITCHES, "recordDate" + " < '" + (System.currentTimeMillis() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null);
log.debug("After ProfileSwitch size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_PROFILESWITCHES));
}
public long size(String database) {
return DatabaseUtils.queryNumEntries(getReadableDatabase(), database);
@ -222,7 +173,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void resetDatabases() {
try {
TableUtils.dropTable(connectionSource, TempTarget.class, true);
TableUtils.dropTable(connectionSource, Treatment.class, true);
TableUtils.dropTable(connectionSource, BgReading.class, true);
TableUtils.dropTable(connectionSource, DanaRHistoryRecord.class, true);
TableUtils.dropTable(connectionSource, DbRequest.class, true);
@ -232,7 +182,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
TableUtils.dropTable(connectionSource, TDD.class, true);
TableUtils.createTableIfNotExists(connectionSource, TempTarget.class);
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
TableUtils.createTableIfNotExists(connectionSource, BgReading.class);
TableUtils.createTableIfNotExists(connectionSource, DanaRHistoryRecord.class);
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
@ -248,7 +197,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
VirtualPumpPlugin.setFakingStatus(true);
scheduleBgChange(null); // trigger refresh
scheduleTemporaryBasalChange();
scheduleTreatmentChange(null);
scheduleExtendedBolusChange();
scheduleTemporaryTargetChange();
scheduleCareportalEventChange();
@ -264,17 +212,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
);
}
public void resetTreatments() {
try {
TableUtils.dropTable(connectionSource, Treatment.class, true);
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
updateEarliestDataChange(0);
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
scheduleTreatmentChange(null);
}
public void resetTempTargets() {
try {
TableUtils.dropTable(connectionSource, TempTarget.class, true);
@ -343,10 +280,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return getDao(TempTarget.class);
}
private Dao<Treatment, Long> getDaoTreatments() throws SQLException {
return getDao(Treatment.class);
}
private Dao<BgReading, Long> getDaoBgReadings() throws SQLException {
return getDao(BgReading.class);
}
@ -379,7 +312,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return getDao(ProfileSwitch.class);
}
public long roundDateToSec(long date) {
public static long roundDateToSec(long date) {
return date - date % 1000;
}
// ------------------- BgReading handling -----------------------
@ -413,7 +346,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
try {
getDaoBgReadings().update(bgReading);
} catch (SQLException e) {
e.printStackTrace();
log.error("Unhandled exception", e);
}
}
@ -513,7 +446,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
// ------------------- TDD handling -----------------------
public void createOrUpdateTDD(TDD tdd){
public void createOrUpdateTDD(TDD tdd) {
try {
Dao<TDD, String> dao = getDaoTDD();
dao.createOrUpdate(tdd);
@ -539,7 +472,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
// ------------- DbRequests handling -------------------
public void create(DbRequest dbr) {
@ -576,7 +508,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
queryBuilder.limit(10L);
PreparedQuery<DbRequest> preparedQuery = queryBuilder.prepare();
List<DbRequest> dbList = getDaoDbRequest().query(preparedQuery);
log.error("deleteDbRequestbyMongoId query size: " + dbList.size());
for (DbRequest r : dbList) {
delete(r);
}
@ -604,147 +535,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
// -------------------- TREATMENT HANDLING -------------------
// return true if new record is created
public boolean createOrUpdate(Treatment treatment) {
try {
Treatment old;
treatment.date = roundDateToSec(treatment.date);
if (treatment.source == Source.PUMP) {
// check for changed from pump change in NS
QueryBuilder<Treatment, Long> queryBuilder = getDaoTreatments().queryBuilder();
Where where = queryBuilder.where();
where.eq("pumpId", treatment.pumpId);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
List<Treatment> trList = getDaoTreatments().query(preparedQuery);
if (trList.size() > 0) {
// do nothing, pump history record cannot be changed
log.debug("TREATMENT: Pump record already found in database: " + treatment.toString());
return false;
}
getDaoTreatments().create(treatment);
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
return true;
}
if (treatment.source == Source.NIGHTSCOUT) {
old = getDaoTreatments().queryForId(treatment.date);
if (old != null) {
if (!old.isEqual(treatment)) {
boolean historyChange = old.isDataChanging(treatment);
long oldDate = old.date;
getDaoTreatments().delete(old); // need to delete/create because date may change too
old.copyFrom(treatment);
getDaoTreatments().create(old);
log.debug("TREATMENT: Updating record by date from: " + Source.getString(treatment.source) + " " + old.toString());
if (historyChange) {
updateEarliestDataChange(oldDate);
updateEarliestDataChange(old.date);
}
scheduleTreatmentChange(treatment);
return true;
}
return false;
}
// find by NS _id
if (treatment._id != null) {
QueryBuilder<Treatment, Long> queryBuilder = getDaoTreatments().queryBuilder();
Where where = queryBuilder.where();
where.eq("_id", treatment._id);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
List<Treatment> trList = getDaoTreatments().query(preparedQuery);
if (trList.size() > 0) {
old = trList.get(0);
if (!old.isEqual(treatment)) {
boolean historyChange = old.isDataChanging(treatment);
long oldDate = old.date;
getDaoTreatments().delete(old); // need to delete/create because date may change too
old.copyFrom(treatment);
getDaoTreatments().create(old);
log.debug("TREATMENT: Updating record by _id from: " + Source.getString(treatment.source) + " " + old.toString());
if (historyChange) {
updateEarliestDataChange(oldDate);
updateEarliestDataChange(old.date);
}
scheduleTreatmentChange(treatment);
return true;
}
}
}
getDaoTreatments().create(treatment);
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
return true;
}
if (treatment.source == Source.USER) {
getDaoTreatments().create(treatment);
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
return true;
}
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return false;
}
public void delete(Treatment treatment) {
try {
getDaoTreatments().delete(treatment);
updateEarliestDataChange(treatment.date);
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
scheduleTreatmentChange(treatment);
}
public void update(Treatment treatment) {
try {
getDaoTreatments().update(treatment);
updateEarliestDataChange(treatment.date);
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
scheduleTreatmentChange(treatment);
}
public void deleteTreatmentById(String _id) {
Treatment stored = findTreatmentById(_id);
if (stored != null) {
log.debug("TREATMENT: Removing Treatment record from database: " + stored.toString());
delete(stored);
updateEarliestDataChange(stored.date);
scheduleTreatmentChange(null);
}
}
@Nullable
private Treatment findTreatmentById(String _id) {
try {
Dao<Treatment, Long> daoTreatments = getDaoTreatments();
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
Where where = queryBuilder.where();
where.eq("_id", _id);
queryBuilder.limit(10L);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
List<Treatment> trList = daoTreatments.query(preparedQuery);
if (trList.size() != 1) {
//log.debug("Treatment findTreatmentById query size: " + trList.size());
return null;
} else {
//log.debug("Treatment findTreatmentById found: " + trList.get(0).log());
return trList.get(0);
}
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return null;
}
private void updateEarliestDataChange(long newDate) {
public static void updateEarliestDataChange(long newDate) {
if (earliestDataChange == null) {
earliestDataChange = newDate;
return;
@ -754,73 +545,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
}
private static void scheduleTreatmentChange(@Nullable final Treatment treatment) {
class PostRunnable implements Runnable {
public void run() {
log.debug("Firing EventTreatmentChange");
MainApp.bus().post(new EventReloadTreatmentData(new EventTreatmentChange(treatment)));
if (earliestDataChange != null)
MainApp.bus().post(new EventNewHistoryData(earliestDataChange));
earliestDataChange = null;
scheduledTratmentPost = null;
}
}
// prepare task for execution in 1 sec
// cancel waiting task to prevent sending multiple posts
if (scheduledTratmentPost != null)
scheduledTratmentPost.cancel(false);
Runnable task = new PostRunnable();
final int sec = 1;
scheduledTratmentPost = treatmentsWorker.schedule(task, sec, TimeUnit.SECONDS);
}
public List<Treatment> getTreatmentDataFromTime(long mills, boolean ascending) {
try {
Dao<Treatment, Long> daoTreatments = getDaoTreatments();
List<Treatment> treatments;
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.ge("date", mills);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
treatments = daoTreatments.query(preparedQuery);
return treatments;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<Treatment>();
}
public void createTreatmentFromJsonIfNotExists(JSONObject trJson) {
try {
Treatment treatment = new Treatment();
treatment.source = Source.NIGHTSCOUT;
treatment.date = roundDateToSec(trJson.getLong("mills"));
treatment.carbs = trJson.has("carbs") ? trJson.getDouble("carbs") : 0;
treatment.insulin = trJson.has("insulin") ? trJson.getDouble("insulin") : 0d;
treatment.pumpId = trJson.has("pumpId") ? trJson.getLong("pumpId") : 0;
treatment._id = trJson.getString("_id");
if (trJson.has("isSMB"))
treatment.isSMB = trJson.getBoolean("isSMB");
if (trJson.has("eventType")) {
treatment.mealBolus = !trJson.get("eventType").equals("Correction Bolus");
double carbs = treatment.carbs;
if (trJson.has("boluscalc")) {
JSONObject boluscalc = trJson.getJSONObject("boluscalc");
if (boluscalc.has("carbs")) {
carbs = Math.max(boluscalc.getDouble("carbs"), carbs);
}
}
if (carbs <= 0)
treatment.mealBolus = false;
}
createOrUpdate(treatment);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
// ---------------- TempTargets handling ---------------
public List<TempTarget> getTemptargetsDataFromTime(long mills, boolean ascending) {
@ -988,7 +712,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
getDaoDanaRHistory().createOrUpdate(record);
//If it is a TDD, store it for stats also.
if(record.recordCode == RecordTypes.RECORD_TYPE_DAILY){
if (record.recordCode == RecordTypes.RECORD_TYPE_DAILY) {
createOrUpdateTDD(new TDD(record.recordDate, record.recordDailyBolus, record.recordDailyBasal, 0));
}
@ -1428,37 +1152,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
*/
public void createExtendedBolusFromJsonIfNotExists(JSONObject trJson) {
try {
QueryBuilder<ExtendedBolus, Long> queryBuilder = null;
queryBuilder = getDaoExtendedBolus().queryBuilder();
Where where = queryBuilder.where();
where.eq("_id", trJson.getString("_id")).or().eq("date", trJson.getLong("mills"));
PreparedQuery<ExtendedBolus> preparedQuery = queryBuilder.prepare();
List<ExtendedBolus> list = getDaoExtendedBolus().query(preparedQuery);
ExtendedBolus extendedBolus;
if (list.size() == 0) {
extendedBolus = new ExtendedBolus();
extendedBolus.source = Source.NIGHTSCOUT;
if (Config.logIncommingData)
log.debug("Adding ExtendedBolus record to database: " + trJson.toString());
// Record does not exists. add
} else if (list.size() == 1) {
extendedBolus = list.get(0);
if (Config.logIncommingData)
log.debug("Updating ExtendedBolus record in database: " + trJson.toString());
} else {
log.error("Something went wrong");
return;
}
extendedBolus.date = trJson.getLong("mills");
extendedBolus.durationInMinutes = trJson.has("duration") ? trJson.getInt("duration") : 0;
extendedBolus.insulin = trJson.getDouble("relative");
extendedBolus._id = trJson.getString("_id");
public void createExtendedBolusFromJsonIfNotExists(JSONObject json) {
ExtendedBolus extendedBolus = ExtendedBolus.createFromJson(json);
if (extendedBolus != null)
createOrUpdate(extendedBolus);
} catch (SQLException | JSONException e) {
log.error("Unhandled exception", e);
}
}
private static void scheduleExtendedBolusChange() {
@ -1504,6 +1201,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
scheduleCareportalEventChange();
}
public CareportalEvent getCareportalEventFromTimestamp(long timestamp) {
try {
return getDaoCareportalEvents().queryForId(timestamp);
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return null;
}
@Nullable
public CareportalEvent getLastCareportalEvent(String event) {
try {
@ -1557,7 +1263,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void deleteCareportalEventById(String _id) {
try {
QueryBuilder<CareportalEvent, Long> queryBuilder = null;
QueryBuilder<CareportalEvent, Long> queryBuilder;
queryBuilder = getDaoCareportalEvents().queryBuilder();
Where where = queryBuilder.where();
where.eq("_id", _id);
@ -1580,7 +1286,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void createCareportalEventFromJsonIfNotExists(JSONObject trJson) {
try {
QueryBuilder<CareportalEvent, Long> queryBuilder = null;
QueryBuilder<CareportalEvent, Long> queryBuilder;
queryBuilder = getDaoCareportalEvents().queryBuilder();
Where where = queryBuilder.where();
where.eq("_id", trJson.getString("_id")).or().eq("date", trJson.getLong("mills"));

View file

@ -9,24 +9,25 @@ import android.graphics.Color;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.Objects;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.data.Iob;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.InsulinInterface;
import info.nightscout.androidaps.interfaces.Interval;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.JsonHelper;
import info.nightscout.utils.Round;
/**
@ -91,6 +92,16 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
pumpId = t.pumpId;
}
public static ExtendedBolus createFromJson(JSONObject json) {
ExtendedBolus extendedBolus = new ExtendedBolus();
extendedBolus.source = Source.NIGHTSCOUT;
extendedBolus.date = JsonHelper.safeGetLong(json, "mills");
extendedBolus.durationInMinutes = JsonHelper.safeGetInt(json, "duration");
extendedBolus.insulin = JsonHelper.safeGetDouble(json, "relative") / 60 * extendedBolus.durationInMinutes;
extendedBolus._id = JsonHelper.safeGetString(json, "_id");
extendedBolus.pumpId = JsonHelper.safeGetLong(json, "pumpId");
return extendedBolus;
}
// -------- Interval interface ---------
Long cuttedEnd = null;

View file

@ -6,7 +6,6 @@ import com.j256.ormlite.table.DatabaseTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.Objects;
import info.nightscout.androidaps.MainApp;
@ -17,6 +16,7 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.InsulinInterface;
import info.nightscout.androidaps.interfaces.Interval;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.SP;
@ -217,7 +217,7 @@ public class TemporaryBasal implements Interval {
// -------- Interval interface end ---------
public IobTotal iobCalc(long time) {
public IobTotal iobCalc(long time, Profile profile) {
if(isFakeExtended){
log.error("iobCalc should only be called on Extended boluses separately");
@ -225,7 +225,6 @@ public class TemporaryBasal implements Interval {
}
IobTotal result = new IobTotal(time);
Profile profile = MainApp.getConfigBuilder().getProfile(time);
InsulinInterface insulinInterface = ConfigBuilderPlugin.getActiveInsulin();
int realDuration = getDurationToTime(time);

View file

@ -0,0 +1,36 @@
package info.nightscout.androidaps.events;
import org.json.JSONObject;
/**
* Event which is published with data fetched from NightScout specific for the
* Treatment-class.
* <p>
* Payload is the from NS retrieved JSON-String which should be handled by all
* subscriber.
*/
public class EventNsTreatment extends Event {
public static final int ADD = 0;
public static final int UPDATE = 1;
public static final int REMOVE = 2;
private final int mode;
private final JSONObject payload;
public EventNsTreatment(int mode, JSONObject payload) {
this.mode = mode;
this.payload = payload;
}
public int getMode() {
return mode;
}
public JSONObject getPayload() {
return payload;
}
}

View file

@ -2,7 +2,7 @@ package info.nightscout.androidaps.events;
import android.support.annotation.Nullable;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
/**
* Created by mike on 04.06.2016.

View file

@ -1,10 +1,7 @@
package info.nightscout.androidaps.interfaces;
import java.util.Date;
import info.nightscout.androidaps.data.Iob;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
/**
* Created by mike on 17.04.2017.

View file

@ -152,10 +152,7 @@ public abstract class PluginBase {
if (getType() == PluginType.PUMP) {
new Thread(() -> {
SystemClock.sleep(3000);
try {
ConfigBuilderPlugin.getCommandQueue().readStatus("Pump driver changed.", null);
} catch (Exception ignored) { // Thread fail to start in tests
}
}).start();
}
}

View file

@ -41,4 +41,7 @@ public class PumpDescription {
public boolean storesCarbInfo = true;
public boolean is30minBasalRatesCapable = false;
public boolean supportsTDDs = false;
public boolean needsManualTDDLoad = true;
}

View file

@ -5,11 +5,12 @@ import java.util.List;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.MealData;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.data.Intervals;
import info.nightscout.androidaps.data.ProfileIntervals;
@ -24,7 +25,7 @@ public interface TreatmentsInterface {
IobTotal getLastCalculationTreatments();
IobTotal getCalculationToTimeTreatments(long time);
IobTotal getLastCalculationTempBasals();
IobTotal getCalculationToTimeTempBasals(long time);
IobTotal getCalculationToTimeTempBasals(long time, Profile profile);
MealData getMealData();

View file

@ -79,7 +79,6 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
tddStats = view.findViewById(R.id.actions_tddstats);
history = view.findViewById(R.id.actions_historybrowser);
profileSwitch.setOnClickListener(this);
tempTarget.setOnClickListener(this);
extendedBolus.setOnClickListener(this);
@ -191,6 +190,9 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
tempTarget.setVisibility(View.GONE);
else
tempTarget.setVisibility(View.VISIBLE);
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().supportsTDDs) tddStats.setVisibility(View.GONE);
else tddStats.setVisibility(View.VISIBLE);
}
});
}

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.Careportal;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
@ -12,7 +13,9 @@ import android.widget.TextView;
import com.squareup.otto.Subscribe;
import info.nightscout.androidaps.BuildConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
@ -21,11 +24,12 @@ import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.events.EventCareportalEventChange;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
import info.nightscout.utils.FabricPrivacy;
public class CareportalFragment extends SubscriberFragment implements View.OnClickListener {
private static Logger log = LoggerFactory.getLogger(CareportalFragment.class);
TextView iage;
TextView cage;
@ -208,26 +212,54 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
public static void updateAge(Activity activity, final TextView sage, final TextView iage, final TextView cage, final TextView pbage) {
if (activity != null) {
activity.runOnUiThread(
new Runnable() {
@Override
public void run() {
() -> {
CareportalEvent careportalEvent;
NSSettingsStatus nsSettings = new NSSettingsStatus().getInstance();
double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 72);
double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 48);
double cageUrgent = nsSettings.getExtendedWarnValue("cage", "urgent", 72);
double cageWarn = nsSettings.getExtendedWarnValue("cage", "warn", 48);
double sageUrgent = nsSettings.getExtendedWarnValue("sage", "urgent", 166);
double sageWarn = nsSettings.getExtendedWarnValue("sage", "warn", 164);
double pbageUrgent = nsSettings.getExtendedWarnValue("pgage", "urgent", 360);
double pbageWarn = nsSettings.getExtendedWarnValue("pgage", "warn", 240);
String notavailable = OverviewFragment.shorttextmode ? "-" : MainApp.sResources.getString(R.string.notavailable);
if (sage != null) {
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SENSORCHANGE);
sage.setText(careportalEvent != null ? careportalEvent.age() : notavailable);
if (careportalEvent != null) {
sage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, sageWarn, sageUrgent));
sage.setText(careportalEvent.age());
} else {
sage.setText(notavailable);
}
}
if (iage != null) {
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.INSULINCHANGE);
iage.setText(careportalEvent != null ? careportalEvent.age() : notavailable);
if (careportalEvent != null) {
iage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, iageWarn, iageUrgent));
iage.setText(careportalEvent.age());
} else {
iage.setText(notavailable);
}
}
if (cage != null) {
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SITECHANGE);
cage.setText(careportalEvent != null ? careportalEvent.age() : notavailable);
if (careportalEvent != null) {
cage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, cageWarn, cageUrgent));
cage.setText(careportalEvent.age());
} else {
cage.setText(notavailable);
}
}
if (pbage != null) {
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.PUMPBATTERYCHANGE);
pbage.setText(careportalEvent != null ? careportalEvent.age() : notavailable);
if (careportalEvent != null) {
pbage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, pbageWarn, pbageUrgent));
pbage.setText(careportalEvent.age());
} else {
pbage.setText(notavailable);
}
}
}
@ -235,4 +267,15 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
}
}
public static int determineTextColor(CareportalEvent careportalEvent, double warnThreshold, double urgentThreshold) {
if (careportalEvent.isOlderThan(urgentThreshold)) {
return MainApp.sResources.getColor(R.color.low);
} else if (careportalEvent.isOlderThan(warnThreshold)) {
return MainApp.sResources.getColor(R.color.high);
} else {
return Color.WHITE;
}
}
}

View file

@ -14,6 +14,8 @@ import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.HardLimits;
import info.nightscout.utils.Round;
@ -55,12 +57,18 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
@Override
public Constraint<Boolean> isClosedLoopAllowed(Constraint<Boolean> value) {
if (!MainApp.isEngineeringModeOrRelease())
value.set(false, MainApp.gs(R.string.closed_loop_disabled_on_dev_branch), this);
String mode = SP.getString("aps_mode", "open");
if (!mode.equals("closed"))
value.set(false, MainApp.gs(R.string.closedmodedisabledinpreferences), this);
if (!MainApp.isEngineeringModeOrRelease()) {
if (value.value()) {
Notification n = new Notification(Notification.TOAST_ALARM, MainApp.gs(R.string.closed_loop_disabled_on_dev_branch), Notification.NORMAL);
MainApp.bus().post(new EventNewNotification(n));
}
value.set(false, MainApp.gs(R.string.closed_loop_disabled_on_dev_branch), this);
}
return value;
}
@ -161,7 +169,11 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
@Override
public Constraint<Double> applyMaxIOBConstraints(Constraint<Double> maxIob) {
double maxIobPref = SP.getDouble(R.string.key_openapsma_max_iob, 1.5d);
double maxIobPref;
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginType.APS))
maxIobPref = SP.getDouble(R.string.key_openapssmb_max_iob, 3d);
else
maxIobPref = SP.getDouble(R.string.key_openapsma_max_iob, 1.5d);
maxIob.setIfSmaller(maxIobPref, String.format(MainApp.gs(R.string.limitingiob), maxIobPref, MainApp.gs(R.string.maxvalueinpreferences)), this);
if (OpenAPSMAPlugin.getPlugin().isEnabled(PluginType.APS))

View file

@ -5,8 +5,6 @@ import com.j256.ormlite.table.DatabaseTable;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Objects;
@ -18,9 +16,7 @@ import info.nightscout.utils.JsonHelper;
@DatabaseTable(tableName = Food.TABLE_FOODS)
public class Food {
private static Logger log = LoggerFactory.getLogger(Food.class);
public static final String TABLE_FOODS = "Foods";
static final String TABLE_FOODS = "Foods";
@DatabaseField(id = true)
public long key;
@ -65,7 +61,7 @@ public class Food {
@DatabaseField
public int gi; // not used yet
public Food() {
private Food() {
key = System.currentTimeMillis();
}

View file

@ -347,6 +347,7 @@ public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
* @param _id
* @return
*/
@Nullable
public Food findByNSId(String _id) {
try {
List<Food> list = this.getDao().queryForEq("_id", _id);

View file

@ -12,7 +12,7 @@ import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.data.Iob;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.interfaces.InsulinInterface;
/**

View file

@ -5,7 +5,7 @@ import com.squareup.otto.Bus;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Iob;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.interfaces.InsulinInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;

View file

@ -10,8 +10,7 @@ import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;

View file

@ -293,13 +293,13 @@ public class IobCobCalculatorPlugin extends PluginBase {
return getBGDataFrom;
}
public IobTotal calculateFromTreatmentsAndTempsSynchronized(long time) {
public IobTotal calculateFromTreatmentsAndTempsSynchronized(long time, Profile profile) {
synchronized (dataLock) {
return calculateFromTreatmentsAndTemps(time);
return calculateFromTreatmentsAndTemps(time, profile);
}
}
public IobTotal calculateFromTreatmentsAndTemps(long time) {
public IobTotal calculateFromTreatmentsAndTemps(long time, Profile profile) {
long now = System.currentTimeMillis();
time = roundUpTime(time);
if (time < now && iobTable.get(time) != null) {
@ -309,16 +309,16 @@ public class IobCobCalculatorPlugin extends PluginBase {
//log.debug(">>> calculateFromTreatmentsAndTemps Cache miss " + new Date(time).toLocaleString());
}
IobTotal bolusIob = TreatmentsPlugin.getPlugin().getCalculationToTimeTreatments(time).round();
IobTotal basalIob = TreatmentsPlugin.getPlugin().getCalculationToTimeTempBasals(time).round();
IobTotal basalIob = TreatmentsPlugin.getPlugin().getCalculationToTimeTempBasals(time, profile).round();
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginType.APS)) {
// Add expected zere temp basal for next 240 mins
// Add expected zero temp basal for next 240 mins
IobTotal basalIobWithZeroTemp = basalIob.copy();
TemporaryBasal t = new TemporaryBasal()
.date(now + 60 * 1000L)
.duration(240)
.absolute(0);
if (t.date < time) {
IobTotal calc = t.iobCalc(time);
IobTotal calc = t.iobCalc(time, profile);
basalIobWithZeroTemp.plus(calc);
}
@ -426,8 +426,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
}
}
public IobTotal[] calculateIobArrayInDia() {
Profile profile = MainApp.getConfigBuilder().getProfile();
public IobTotal[] calculateIobArrayInDia(Profile profile) {
// predict IOB out to DIA plus 30m
long time = System.currentTimeMillis();
time = roundUpTime(time);
@ -436,15 +435,14 @@ public class IobCobCalculatorPlugin extends PluginBase {
int pos = 0;
for (int i = 0; i < len; i++) {
long t = time + i * 5 * 60000;
IobTotal iob = calculateFromTreatmentsAndTempsSynchronized(t);
IobTotal iob = calculateFromTreatmentsAndTempsSynchronized(t, profile);
array[pos] = iob;
pos++;
}
return array;
}
public IobTotal[] calculateIobArrayForSMB() {
Profile profile = MainApp.getConfigBuilder().getProfile();
public IobTotal[] calculateIobArrayForSMB(Profile profile) {
// predict IOB out to DIA plus 30m
long time = System.currentTimeMillis();
time = roundUpTime(time);
@ -453,7 +451,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
int pos = 0;
for (int i = 0; i < len; i++) {
long t = time + i * 5 * 60000;
IobTotal iob = calculateFromTreatmentsAndTempsSynchronized(t);
IobTotal iob = calculateFromTreatmentsAndTempsSynchronized(t, profile);
array[pos] = iob;
pos++;
}
@ -479,6 +477,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
}
@Subscribe
@SuppressWarnings("unused")
public void onEventAppInitialized(EventAppInitialized ev) {
if (this != getPlugin()) {
log.debug("Ignoring event for non default instance");
@ -488,6 +487,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
}
@Subscribe
@SuppressWarnings("unused")
public void onEventNewBG(EventNewBG ev) {
if (this != getPlugin()) {
log.debug("Ignoring event for non default instance");

View file

@ -20,7 +20,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
@ -138,7 +138,7 @@ public class IobCobThread extends Thread {
delta = (bg - bucketed_data.get(i + 1).value);
avgDelta = (bg - bucketed_data.get(i + 3).value) / 3;
IobTotal iob = iobCobCalculatorPlugin.calculateFromTreatmentsAndTemps(bgTime);
IobTotal iob = iobCobCalculatorPlugin.calculateFromTreatmentsAndTemps(bgTime, profile);
double bgi = -iob.activity * sens * 5;
double deviation = delta - bgi;
@ -155,6 +155,7 @@ public class IobCobThread extends Thread {
AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago);
if (hourAgoData != null) {
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
if (Config.logAutosensData)
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString());
int past = 1;
try {
@ -242,6 +243,7 @@ public class IobCobThread extends Thread {
previous = autosensData;
autosensDataTable.put(bgTime, autosensData);
if (Config.logAutosensData)
log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime));
autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio;
if (Config.logAutosensData)

View file

@ -1,11 +1,14 @@
package info.nightscout.androidaps.plugins.Loop;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import com.crashlytics.android.answers.CustomEvent;
@ -48,6 +51,9 @@ import info.nightscout.utils.SP;
public class LoopPlugin extends PluginBase {
private static Logger log = LoggerFactory.getLogger(LoopPlugin.class);
public static final String CHANNEL_ID = "AndroidAPS-Openloop";
protected static LoopPlugin loopPlugin;
public static LoopPlugin getPlugin() {
@ -90,9 +96,22 @@ public class LoopPlugin extends PluginBase {
@Override
protected void onStart() {
MainApp.bus().register(this);
createNotificationChannel();
super.onStart();
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager mNotificationManager =
(NotificationManager) MainApp.instance().getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
@SuppressLint("WrongConstant") NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
CHANNEL_ID,
NotificationManager.IMPORTANCE_HIGH);
mNotificationManager.createNotificationChannel(channel);
}
}
@Override
protected void onStop() {
super.onStop();
@ -322,7 +341,7 @@ public class LoopPlugin extends PluginBase {
} else {
if (result.isChangeRequested() && allowNotification) {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(MainApp.instance().getApplicationContext());
new NotificationCompat.Builder(MainApp.instance().getApplicationContext(), CHANNEL_ID);
builder.setSmallIcon(R.drawable.notif_icon)
.setContentTitle(MainApp.sResources.getString(R.string.openloop_newsuggestion))
.setContentText(resultAfterConstraints.toString())

View file

@ -170,6 +170,19 @@ public class NSSettingsStatus {
}
// valid property is "warn" or "urgent"
// plugings "iage" "sage" "cage" "pbage"
public double getExtendedWarnValue(String plugin, String property, double defaultvalue) {
JSONObject extendedSettings = this.getExtendedSettings();
if (extendedSettings == null)
return defaultvalue;
JSONObject pluginJson = extendedSettings.optJSONObject(plugin);
if (pluginJson == null)
return defaultvalue;
return pluginJson.optDouble(property, defaultvalue);
}
public String getActiveProfile() {
return getStringOrNull("activeProfile");
}
@ -193,7 +206,7 @@ public class NSSettingsStatus {
return result;
}
}
if (settingsO.has("alarmTimeagoWarnMins") && Objects.equals(what, "alarmTimeagoWarnMins")){
if (settingsO.has("alarmTimeagoWarnMins") && Objects.equals(what, "alarmTimeagoWarnMins")) {
Double result = settingsO.getDouble(what);
return result;
}
@ -206,7 +219,7 @@ public class NSSettingsStatus {
private String getStringOrNull(String key) {
String ret = null;
if(data == null) return null;
if (data == null) return null;
if (data.has(key)) {
try {
ret = data.getString(key);
@ -315,7 +328,7 @@ public class NSSettingsStatus {
public JSONObject extentendedPumpSettings() {
try {
JSONObject extended = getExtendedSettings();
if(extended == null) return null;
if (extended == null) return null;
if (extended.has("pump")) {
JSONObject pump = extended.getJSONObject("pump");
return pump;

View file

@ -136,7 +136,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
Date start = new Date();
Date startPart = new Date();
IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayInDia();
IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayInDia(profile);
Profiler.log(log, "calculateIobArrayInDia()", startPart);
startPart = new Date();

View file

@ -143,7 +143,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
Date start = new Date();
Date startPart = new Date();
IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayForSMB();
IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayForSMB(profile);
Profiler.log(log, "calculateIobArrayInDia()", startPart);
startPart = new Date();

View file

@ -111,6 +111,7 @@ import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotificati
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationRecyclerViewAdapter;
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationStore;
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin;
@ -460,32 +461,32 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
final PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription();
if (activeloop == null || !MainApp.getConfigBuilder().isProfileValid("ContexMenuCreation"))
return;
menu.setHeaderTitle(MainApp.sResources.getString(R.string.loop));
menu.setHeaderTitle(MainApp.gs(R.string.loop));
if (activeloop.isEnabled(PluginType.LOOP)) {
menu.add(MainApp.sResources.getString(R.string.disableloop));
menu.add(MainApp.gs(R.string.disableloop));
if (!activeloop.isSuspended()) {
menu.add(MainApp.sResources.getString(R.string.suspendloopfor1h));
menu.add(MainApp.sResources.getString(R.string.suspendloopfor2h));
menu.add(MainApp.sResources.getString(R.string.suspendloopfor3h));
menu.add(MainApp.sResources.getString(R.string.suspendloopfor10h));
menu.add(MainApp.gs(R.string.suspendloopfor1h));
menu.add(MainApp.gs(R.string.suspendloopfor2h));
menu.add(MainApp.gs(R.string.suspendloopfor3h));
menu.add(MainApp.gs(R.string.suspendloopfor10h));
if (pumpDescription.tempDurationStep15mAllowed)
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor15m));
menu.add(MainApp.gs(R.string.disconnectpumpfor15m));
if (pumpDescription.tempDurationStep30mAllowed)
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor30m));
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor1h));
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor2h));
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor3h));
menu.add(MainApp.gs(R.string.disconnectpumpfor30m));
menu.add(MainApp.gs(R.string.disconnectpumpfor1h));
menu.add(MainApp.gs(R.string.disconnectpumpfor2h));
menu.add(MainApp.gs(R.string.disconnectpumpfor3h));
} else {
menu.add(MainApp.sResources.getString(R.string.resume));
menu.add(MainApp.gs(R.string.resume));
}
}
if (!activeloop.isEnabled(PluginType.LOOP))
menu.add(MainApp.sResources.getString(R.string.enableloop));
menu.add(MainApp.gs(R.string.enableloop));
} else if (v == activeProfileView) {
menu.setHeaderTitle(MainApp.sResources.getString(R.string.profile));
menu.add(MainApp.sResources.getString(R.string.danar_viewprofile));
menu.setHeaderTitle(MainApp.gs(R.string.profile));
menu.add(MainApp.gs(R.string.danar_viewprofile));
if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
menu.add(MainApp.sResources.getString(R.string.careportal_profileswitch));
menu.add(MainApp.gs(R.string.careportal_profileswitch));
}
}
}
@ -496,7 +497,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (profile == null)
return true;
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
if (item.getTitle().equals(MainApp.sResources.getString(R.string.disableloop))) {
if (item.getTitle().equals(MainApp.gs(R.string.disableloop))) {
activeloop.setPluginEnabled(PluginType.LOOP, false);
activeloop.setFragmentVisible(PluginType.LOOP, false);
MainApp.getConfigBuilder().storeSettings("DisablingLoop");
@ -505,75 +506,75 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
@Override
public void run() {
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(24 * 60); // upload 24h, we don't know real duration
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.enableloop))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.enableloop))) {
activeloop.setPluginEnabled(PluginType.LOOP, true);
activeloop.setFragmentVisible(PluginType.LOOP, true);
MainApp.getConfigBuilder().storeSettings("EnablingLoop");
updateGUI("suspendmenu");
NSUpload.uploadOpenAPSOffline(0);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.resume))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.resume))) {
activeloop.suspendTo(0L);
updateGUI("suspendmenu");
MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() {
@Override
public void run() {
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(0);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor1h))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor1h))) {
MainApp.getConfigBuilder().suspendLoop(60);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor2h))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor2h))) {
MainApp.getConfigBuilder().suspendLoop(120);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor3h))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor3h))) {
MainApp.getConfigBuilder().suspendLoop(180);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor10h))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor10h))) {
MainApp.getConfigBuilder().suspendLoop(600);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor15m))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor15m))) {
MainApp.getConfigBuilder().disconnectPump(15, profile);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor30m))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor30m))) {
MainApp.getConfigBuilder().disconnectPump(30, profile);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor1h))) {
MainApp.getConfigBuilder().disconnectPump(60, profile);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor2h))) {
MainApp.getConfigBuilder().disconnectPump(120, profile);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor3h))) {
MainApp.getConfigBuilder().disconnectPump(180, profile);
updateGUI("suspendmenu");
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.careportal_profileswitch))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.careportal_profileswitch))) {
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT;
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.danar_viewprofile))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.danar_viewprofile))) {
ProfileViewerDialog pvd = ProfileViewerDialog.newInstance(System.currentTimeMillis());
FragmentManager manager = getFragmentManager();
pvd.show(manager, "ProfileViewDialog");
@ -753,9 +754,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (!insulinAfterConstraints.equals(wizard.calculatedTotalInsulin) || !carbsAfterConstraints.equals(quickWizardEntry.carbs())) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.sResources.getString(R.string.treatmentdeliveryerror));
builder.setTitle(MainApp.gs(R.string.treatmentdeliveryerror));
builder.setMessage(getString(R.string.constraints_violation) + "\n" + getString(R.string.changeyourinput));
builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), null);
builder.setPositiveButton(MainApp.gs(R.string.ok), null);
builder.show();
return;
}
@ -765,7 +766,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
final Context context = getContext();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
accepted = false;
builder.setTitle(MainApp.sResources.getString(R.string.confirmation));
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(confirmMessage);
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
@ -789,7 +790,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
@ -810,7 +811,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror));
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
@ -841,12 +842,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
public void onResume() {
super.onResume();
MainApp.bus().register(this);
sRefreshLoop = new Runnable() {
@Override
public void run() {
sRefreshLoop = () -> {
scheduleUpdateGUI("refreshLoop");
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
}
};
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
registerForContextMenu(apsModeView);
@ -894,23 +892,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
scheduleUpdateGUI("EventExtendedBolusChange");
}
// Handled by EventAutosensCalculationFinished
// @Subscribe
// public void onStatusEvent(final EventNewBG ev) {
// scheduleUpdateGUI("EventNewBG");
// }
@Subscribe
public void onStatusEvent(final EventNewOpenLoopNotification ev) {
scheduleUpdateGUI("EventNewOpenLoopNotification");
}
// Handled by EventAutosensCalculationFinished
// @Subscribe
// public void onStatusEvent(final EventNewBasalProfile ev) {
// scheduleUpdateGUI("EventNewBasalProfile");
// }
@Subscribe
public void onStatusEvent(final EventTempTargetChange ev) {
scheduleUpdateGUI("EventTempTargetChange");
@ -920,12 +906,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
public void onStatusEvent(final EventPumpStatusChanged s) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
updatePumpStatus(s.textStatus());
}
});
activity.runOnUiThread(() -> updatePumpStatus(s.textStatus()));
}
private void hideTempRecommendation() {
@ -962,12 +943,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
public void run() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.runOnUiThread(() -> {
updateGUI(from);
scheduledUpdate = null;
}
});
}
}
@ -1032,7 +1010,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
avgdeltaView.setText("øΔ15m: " + Profile.toUnitsString(glucoseStatus.short_avgdelta, glucoseStatus.short_avgdelta * Constants.MGDL_TO_MMOLL, units) +
" øΔ40m: " + Profile.toUnitsString(glucoseStatus.long_avgdelta, glucoseStatus.long_avgdelta * Constants.MGDL_TO_MMOLL, units));
} else {
deltaView.setText("Δ " + MainApp.sResources.getString(R.string.notavailable));
deltaView.setText("Δ " + MainApp.gs(R.string.notavailable));
if (avgdeltaView != null)
avgdeltaView.setText("");
}
@ -1049,25 +1027,29 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isSuperBolus()) {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.looppumpsuspended));
apsModeView.setText(String.format(MainApp.sResources.getString(R.string.loopsuperbolusfor), activeloop.minutesToEndOfSuspend()));
apsModeView.setText(String.format(MainApp.gs(R.string.loopsuperbolusfor), activeloop.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
} else if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isDisconnected()) {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.looppumpsuspended));
apsModeView.setText(String.format(MainApp.gs(R.string.loopdisconnectedfor), activeloop.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
} else if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isSuspended()) {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.looppumpsuspended));
apsModeView.setText(String.format(MainApp.sResources.getString(R.string.loopsuspendedfor), activeloop.minutesToEndOfSuspend()));
apsModeView.setText(String.format(MainApp.gs(R.string.loopsuspendedfor), activeloop.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
} else if (pump.isSuspended()) {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.looppumpsuspended));
apsModeView.setText(MainApp.sResources.getString(R.string.pumpsuspended));
apsModeView.setText(MainApp.gs(R.string.pumpsuspended));
apsModeView.setTextColor(Color.WHITE);
} else if (activeloop != null && activeloop.isEnabled(activeloop.getType())) {
if (closedLoopEnabled.value()) {
apsModeView.setText(MainApp.sResources.getString(R.string.closedloop));
apsModeView.setText(MainApp.gs(R.string.closedloop));
} else {
apsModeView.setText(MainApp.sResources.getString(R.string.openloop));
apsModeView.setText(MainApp.gs(R.string.openloop));
}
} else {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.loopdisabled));
apsModeView.setText(MainApp.sResources.getString(R.string.disabledloop));
apsModeView.setText(MainApp.gs(R.string.disabledloop));
apsModeView.setTextColor(Color.WHITE);
}
} else {
@ -1135,11 +1117,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
baseBasalView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String fullText = MainApp.sResources.getString(R.string.pump_basebasalrate_label) + ": " + DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h\n";
String fullText = MainApp.gs(R.string.pump_basebasalrate_label) + ": " + DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h\n";
if (activeTemp != null) {
fullText += MainApp.sResources.getString(R.string.pump_tempbasal_label) + ": " + activeTemp.toStringFull();
fullText += MainApp.gs(R.string.pump_tempbasal_label) + ": " + activeTemp.toStringFull();
}
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.basal), fullText, null);
OKDialog.show(getActivity(), MainApp.gs(R.string.basal), fullText, null);
}
});
@ -1173,7 +1155,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
extendedBolusView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.extendedbolus), extendedBolus.toString(), null);
OKDialog.show(getActivity(), MainApp.gs(R.string.extendedbolus), extendedBolus.toString(), null);
}
});
@ -1192,9 +1174,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
activeProfileView.setText(MainApp.getConfigBuilder().getProfileName());
activeProfileView.setBackgroundColor(Color.GRAY);
tempTargetView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
tempTargetView.setOnLongClickListener(view -> {
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog();
final OptionsToShow temptarget = CareportalFragment.TEMPTARGET;
@ -1202,7 +1182,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget);
newTTDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
return true;
}
});
tempTargetView.setLongClickable(true);
@ -1276,14 +1255,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (shorttextmode) {
String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U";
iobView.setText(iobtext);
iobView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U\n"
iobView.setOnClickListener(v -> {
String iobtext1 = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U\n"
+ getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U\n"
+ getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U\n";
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.iob), iobtext, null);
}
OKDialog.show(getActivity(), MainApp.gs(R.string.iob), iobtext1, null);
});
} else if (MainApp.sResources.getBoolean(R.bool.isTablet)) {
String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U ("
@ -1310,41 +1286,24 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
// pump status from ns
if (pumpDeviceStatusView != null) {
pumpDeviceStatusView.setText(NSDeviceStatus.getInstance().getPumpStatus());
pumpDeviceStatusView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.pump), NSDeviceStatus.getInstance().getExtendedPumpStatus(), null);
}
});
pumpDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.pump), NSDeviceStatus.getInstance().getExtendedPumpStatus(), null));
}
// OpenAPS status from ns
if (openapsDeviceStatusView != null) {
openapsDeviceStatusView.setText(NSDeviceStatus.getInstance().getOpenApsStatus());
openapsDeviceStatusView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.openaps), NSDeviceStatus.getInstance().getExtendedOpenApsStatus(), null);
}
});
openapsDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.openaps), NSDeviceStatus.getInstance().getExtendedOpenApsStatus(), null));
}
// Uploader status from ns
if (uploaderDeviceStatusView != null) {
uploaderDeviceStatusView.setText(NSDeviceStatus.getInstance().getUploaderStatus());
uploaderDeviceStatusView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus(), null);
}
});
uploaderDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus(), null));
}
// ****** GRAPH *******
new Thread(new Runnable() {
@Override
public void run() {
new Thread(() -> {
// allign to hours
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
@ -1448,9 +1407,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
// do GUI update
FragmentActivity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.runOnUiThread(() -> {
if (SP.getBoolean("showiob", true) || SP.getBoolean("showcob", true) || SP.getBoolean("showdeviations", false) || SP.getBoolean("showratios", false) || Config.displayDeviationSlope) {
iobGraph.setVisibility(View.VISIBLE);
} else {
@ -1460,118 +1417,26 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
graphData.performUpdate();
secondGraphData.performUpdate();
Profiler.log(log, from + " - onDataChanged", updateGUIStart);
}
});
}
}
}).start();
Profiler.log(log, from, updateGUIStart);
}
//Notifications
static class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.NotificationsViewHolder> {
List<Notification> notificationsList;
RecyclerViewAdapter(List<Notification> notificationsList) {
this.notificationsList = notificationsList;
}
@Override
public NotificationsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.overview_notification_item, viewGroup, false);
return new NotificationsViewHolder(v);
}
@Override
public void onBindViewHolder(NotificationsViewHolder holder, int position) {
Notification notification = notificationsList.get(position);
holder.dismiss.setTag(notification);
if (Objects.equals(notification.text, MainApp.sResources.getString(R.string.nsalarm_staledata)))
holder.dismiss.setText("snooze");
holder.text.setText(notification.text);
holder.time.setText(DateUtil.timeString(notification.date));
if (notification.level == Notification.URGENT)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationUrgent));
else if (notification.level == Notification.NORMAL)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationNormal));
else if (notification.level == Notification.LOW)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationLow));
else if (notification.level == Notification.INFO)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationInfo));
else if (notification.level == Notification.ANNOUNCEMENT)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationAnnouncement));
}
@Override
public int getItemCount() {
return notificationsList.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
static class NotificationsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CardView cv;
TextView time;
TextView text;
Button dismiss;
NotificationsViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.notification_cardview);
time = (TextView) itemView.findViewById(R.id.notification_time);
text = (TextView) itemView.findViewById(R.id.notification_text);
dismiss = (Button) itemView.findViewById(R.id.notification_dismiss);
dismiss.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Notification notification = (Notification) v.getTag();
switch (v.getId()) {
case R.id.notification_dismiss:
MainApp.bus().post(new EventDismissNotification(notification.id));
if (notification.nsAlarm != null) {
BroadcastAckAlarm.handleClearAlarm(notification.nsAlarm, MainApp.instance().getApplicationContext(), 60 * 60 * 1000L);
}
// Adding current time to snooze if we got staleData
log.debug("Notification text is: " + notification.text);
if (notification.text.equals(MainApp.sResources.getString(R.string.nsalarm_staledata))) {
NotificationStore nstore = OverviewPlugin.getPlugin().notificationStore;
long msToSnooze = SP.getInt("nsalarm_staledatavalue", 15) * 60 * 1000L;
log.debug("snooze nsalarm_staledatavalue in minutes is " + SP.getInt("nsalarm_staledatavalue", 15) + "\n in ms is: " + msToSnooze + " currentTimeMillis is: " + System.currentTimeMillis());
nstore.snoozeTo(System.currentTimeMillis() + (SP.getInt("nsalarm_staledatavalue", 15) * 60 * 1000L));
}
break;
}
}
}
}
void updateNotifications() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
NotificationStore nstore = OverviewPlugin.getPlugin().notificationStore;
nstore.removeExpired();
nstore.unSnooze();
if (nstore.store.size() > 0) {
RecyclerViewAdapter adapter = new RecyclerViewAdapter(nstore.store);
NotificationRecyclerViewAdapter adapter = new NotificationRecyclerViewAdapter(nstore.store);
notificationsView.setAdapter(adapter);
notificationsView.setVisibility(View.VISIBLE);
} else {
notificationsView.setVisibility(View.GONE);
}
}
});
}
}

View file

@ -72,7 +72,7 @@ public class OverviewPlugin extends PluginBase {
@Subscribe
public void onStatusEvent(final EventNewNotification n) {
notificationStore.add(n.notification);
if (notificationStore.add(n.notification))
MainApp.bus().post(new EventRefreshOverview("EventNewNotification"));
}

View file

@ -3,8 +3,7 @@ package info.nightscout.androidaps.plugins.Overview.events;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.Event;
public class EventOverviewBolusProgress extends Event {

View file

@ -23,7 +23,6 @@ import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
import info.nightscout.androidaps.plugins.IobCobCalculator.BasalData;
@ -38,6 +37,7 @@ import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLab
import info.nightscout.androidaps.plugins.Overview.graphExtensions.Scale;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.ScaledDataPoint;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.TimeAsXAxisLabelFormatter;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.Round;
@ -334,7 +334,10 @@ public class GraphData {
Scale iobScale = new Scale();
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
double iob = IobCobCalculatorPlugin.getPlugin().calculateFromTreatmentsAndTempsSynchronized(time).iob;
Profile profile = MainApp.getConfigBuilder().getProfile(time);
double iob = 0d;
if (profile != null)
iob = IobCobCalculatorPlugin.getPlugin().calculateFromTreatmentsAndTempsSynchronized(time, profile).iob;
if (Math.abs(lastIob - iob) > 0.02) {
if (Math.abs(lastIob - iob) > 0.2)
iobArray.add(new ScaledDataPoint(time, lastIob, iobScale));

View file

@ -0,0 +1,107 @@
package info.nightscout.androidaps.plugins.Overview.notifications;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Objects;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastAckAlarm;
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.SP;
public class NotificationRecyclerViewAdapter extends RecyclerView.Adapter<NotificationRecyclerViewAdapter.NotificationsViewHolder> {
private static Logger log = LoggerFactory.getLogger(NotificationRecyclerViewAdapter.class);
private List<Notification> notificationsList;
public NotificationRecyclerViewAdapter(List<Notification> notificationsList) {
this.notificationsList = notificationsList;
}
@Override
public NotificationsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.overview_notification_item, viewGroup, false);
return new NotificationsViewHolder(v);
}
@Override
public void onBindViewHolder(NotificationsViewHolder holder, int position) {
Notification notification = notificationsList.get(position);
holder.dismiss.setTag(notification);
if (Objects.equals(notification.text, MainApp.gs(R.string.nsalarm_staledata)))
holder.dismiss.setText("snooze");
holder.text.setText(notification.text);
holder.time.setText(DateUtil.timeString(notification.date));
if (notification.level == Notification.URGENT)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationUrgent));
else if (notification.level == Notification.NORMAL)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationNormal));
else if (notification.level == Notification.LOW)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationLow));
else if (notification.level == Notification.INFO)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationInfo));
else if (notification.level == Notification.ANNOUNCEMENT)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationAnnouncement));
}
@Override
public int getItemCount() {
return notificationsList.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
static class NotificationsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CardView cv;
TextView time;
TextView text;
Button dismiss;
NotificationsViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.notification_cardview);
time = (TextView) itemView.findViewById(R.id.notification_time);
text = (TextView) itemView.findViewById(R.id.notification_text);
dismiss = (Button) itemView.findViewById(R.id.notification_dismiss);
dismiss.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Notification notification = (Notification) v.getTag();
switch (v.getId()) {
case R.id.notification_dismiss:
MainApp.bus().post(new EventDismissNotification(notification.id));
if (notification.nsAlarm != null) {
BroadcastAckAlarm.handleClearAlarm(notification.nsAlarm, MainApp.instance().getApplicationContext(), 60 * 60 * 1000L);
}
// Adding current time to snooze if we got staleData
log.debug("Notification text is: " + notification.text);
if (notification.text.equals(MainApp.sResources.getString(R.string.nsalarm_staledata))) {
NotificationStore nstore = OverviewPlugin.getPlugin().notificationStore;
long msToSnooze = SP.getInt("nsalarm_staledatavalue", 15) * 60 * 1000L;
log.debug("snooze nsalarm_staledatavalue in minutes is " + SP.getInt("nsalarm_staledatavalue", 15) + "\n in ms is: " + msToSnooze + " currentTimeMillis is: " + System.currentTimeMillis());
nstore.snoozeTo(System.currentTimeMillis() + (SP.getInt("nsalarm_staledatavalue", 15) * 60 * 1000L));
}
break;
}
}
}
}

View file

@ -1,5 +1,7 @@
package info.nightscout.androidaps.plugins.Overview.notifications;
import android.annotation.SuppressLint;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
@ -8,6 +10,7 @@ import android.graphics.BitmapFactory;
import android.media.AudioAttributes;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import org.slf4j.Logger;
@ -28,11 +31,15 @@ import info.nightscout.utils.SP;
*/
public class NotificationStore {
public static final String CHANNEL_ID = "AndroidAPS-Overview";
private static Logger log = LoggerFactory.getLogger(NotificationStore.class);
public List<Notification> store = new ArrayList<Notification>();
public long snoozedUntil = 0L;
public NotificationStore() {
createNotificationChannel();
}
public class NotificationComparator implements Comparator<Notification> {
@ -42,13 +49,13 @@ public class NotificationStore {
}
}
public synchronized void add(Notification n) {
public synchronized boolean add(Notification n) {
log.info("Notification received: " + n.text);
for (Notification storeNotification : store) {
if (storeNotification.id == n.id) {
storeNotification.date = n.date;
storeNotification.validTo = n.validTo;
return;
return false;
}
}
store.add(n);
@ -64,6 +71,7 @@ public class NotificationStore {
}
Collections.sort(store, new NotificationComparator());
return true;
}
public synchronized boolean remove(int id) {
@ -110,7 +118,7 @@ public class NotificationStore {
Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), R.mipmap.blueowl);
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(context)
new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setLargeIcon(largeIcon)
.setContentText(n.text)
@ -127,4 +135,17 @@ public class NotificationStore {
}
mgr.notify(n.id, notificationBuilder.build());
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager mNotificationManager =
(NotificationManager) MainApp.instance().getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
@SuppressLint("WrongConstant") NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
CHANNEL_ID,
NotificationManager.IMPORTANCE_HIGH);
mNotificationManager.createNotificationChannel(channel);
}
}
}

View file

@ -1,11 +1,14 @@
package info.nightscout.androidaps.plugins.Persistentnotification;
import android.annotation.SuppressLint;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
@ -41,6 +44,8 @@ import info.nightscout.utils.DecimalFormatter;
public class PersistentNotificationPlugin extends PluginBase {
public static final String CHANNEL_ID = "AndroidAPS-Ongoing";
private static final int ONGOING_NOTIFICATION_ID = 4711;
private final Context ctx;
@ -57,10 +62,23 @@ public class PersistentNotificationPlugin extends PluginBase {
@Override
protected void onStart() {
MainApp.bus().register(this);
createNotificationChannel();
updateNotification();
super.onStart();
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager mNotificationManager =
(NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
@SuppressLint("WrongConstant") NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
CHANNEL_ID,
NotificationManager.IMPORTANCE_HIGH);
mNotificationManager.createNotificationChannel(channel);
}
}
@Override
protected void onStop() {
MainApp.bus().unregister(this);
@ -118,7 +136,7 @@ public class PersistentNotificationPlugin extends PluginBase {
line3 += " - " + MainApp.getConfigBuilder().getProfileName();
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx);
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, CHANNEL_ID);
builder.setOngoing(true);
builder.setCategory(NotificationCompat.CATEGORY_STATUS);
builder.setSmallIcon(R.drawable.ic_notification);

View file

@ -4,6 +4,7 @@ package info.nightscout.androidaps.plugins.ProfileLocal;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentTransaction;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
@ -48,21 +49,16 @@ public class LocalProfileFragment extends SubscriberFragment {
TimeListEdit basalView;
TimeListEdit targetView;
Button profileswitchButton;
Button resetButton;
Button saveButton;
TextView invalidProfile;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
Runnable save = new Runnable() {
@Override
public void run() {
LocalProfilePlugin.getPlugin().storeSettings();
Runnable save = () -> {
doEdit();
if (basalView != null) {
basalView.updateLabel(MainApp.sResources.getString(R.string.nsprofileview_basal_label) + ": " + getSumLabel());
}
updateGUI();
}
};
TextWatcher textWatch = new TextWatcher() {
@ -80,13 +76,16 @@ public class LocalProfileFragment extends SubscriberFragment {
public void onTextChanged(CharSequence s, int start,
int before, int count) {
LocalProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(diaView.getText().toString());
LocalProfilePlugin.getPlugin().storeSettings();
updateGUI();
doEdit();
}
};
PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription();
View layout = inflater.inflate(R.layout.localprofile_fragment, container, false);
diaView = (NumberPicker) layout.findViewById(R.id.localprofile_dia);
diaView.setParams(LocalProfilePlugin.getPlugin().dia, 2d, 48d, 0.1d, new DecimalFormat("0.0"), false, textWatch);
@ -97,6 +96,10 @@ public class LocalProfileFragment extends SubscriberFragment {
basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.sResources.getString(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save);
targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.sResources.getString(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3d, 200, 0.1d, new DecimalFormat("0.0"), save);
profileswitchButton = (Button) layout.findViewById(R.id.localprofile_profileswitch);
resetButton = (Button) layout.findViewById(R.id.localprofile_reset);
saveButton = (Button) layout.findViewById(R.id.localprofile_save);
invalidProfile = (TextView) layout.findViewById(R.id.invalidprofile);
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable) {
@ -112,7 +115,7 @@ public class LocalProfileFragment extends SubscriberFragment {
LocalProfilePlugin.getPlugin().mgdl = mgdlView.isChecked();
LocalProfilePlugin.getPlugin().mmol = !LocalProfilePlugin.getPlugin().mgdl;
mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol);
LocalProfilePlugin.getPlugin().storeSettings();
doEdit();
}
});
mmolView.setOnClickListener(new View.OnClickListener() {
@ -121,7 +124,7 @@ public class LocalProfileFragment extends SubscriberFragment {
LocalProfilePlugin.getPlugin().mmol = mmolView.isChecked();
LocalProfilePlugin.getPlugin().mgdl = !LocalProfilePlugin.getPlugin().mmol;
mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl);
LocalProfilePlugin.getPlugin().storeSettings();
doEdit();
}
});
@ -136,6 +139,25 @@ public class LocalProfileFragment extends SubscriberFragment {
}
});
resetButton.setOnClickListener(view -> {
LocalProfilePlugin.getPlugin().loadSettings();
mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl);
mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol);
diaView.setParams(LocalProfilePlugin.getPlugin().dia, 2d, 48d, 0.1d, new DecimalFormat("0.0"), false, textWatch);
icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.sResources.getString(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50d, 0.1d, new DecimalFormat("0.0"), save);
isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.sResources.getString(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500d, 0.1d, new DecimalFormat("0.0"), save);
basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.sResources.getString(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save);
targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.sResources.getString(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3d, 200, 0.1d, new DecimalFormat("0.0"), save);
updateGUI();
});
saveButton.setOnClickListener(view -> {
if(!LocalProfilePlugin.getPlugin().isValidEditState()){
return; //Should not happen as saveButton should not be visible if not valid
}
LocalProfilePlugin.getPlugin().storeSettings();
updateGUI();
});
return layout;
} catch (Exception e) {
@ -146,9 +168,14 @@ public class LocalProfileFragment extends SubscriberFragment {
return null;
}
public void doEdit() {
LocalProfilePlugin.getPlugin().setEdited(true);
updateGUI();
}
@NonNull
public String getSumLabel() {
ProfileStore profile = LocalProfilePlugin.getPlugin().getProfile();
ProfileStore profile = LocalProfilePlugin.getPlugin().createProfileStore();
if (profile != null)
return "" + DecimalFormatter.to2Decimal(profile.getDefaultProfile().baseBasalSum()) + "U";
else
@ -167,16 +194,39 @@ public class LocalProfileFragment extends SubscriberFragment {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
boolean isValid = LocalProfilePlugin.getPlugin().getProfile() != null && LocalProfilePlugin.getPlugin().getProfile().getDefaultProfile().isValid(MainApp.gs(R.string.localprofile));
if (!ConfigBuilderPlugin.getActivePump().isInitialized() || ConfigBuilderPlugin.getActivePump().isSuspended() || !isValid) {
boolean isValid = LocalProfilePlugin.getPlugin().isValidEditState();
boolean isEdited = LocalProfilePlugin.getPlugin().isEdited();
if (isValid) {
invalidProfile.setVisibility(View.GONE); //show invalid profile
if (isEdited || !ConfigBuilderPlugin.getActivePump().isInitialized() || ConfigBuilderPlugin.getActivePump().isSuspended()) {
//edited profile -> save first
//pump not initialized -> don't update profile yet
profileswitchButton.setVisibility(View.GONE);
} else {
profileswitchButton.setVisibility(View.VISIBLE);
}
if (isValid)
invalidProfile.setVisibility(View.GONE);
else
if(isEdited){
saveButton.setVisibility(View.VISIBLE);
} else {
saveButton.setVisibility(View.GONE);
}
} else {
invalidProfile.setVisibility(View.VISIBLE);
profileswitchButton.setVisibility(View.GONE);
saveButton.setVisibility(View.GONE); //don't save an invalid profile
}
//Show reset button iff data was edited
if(isEdited) {
resetButton.setVisibility(View.VISIBLE);
} else {
resetButton.setVisibility(View.GONE);
}
}
});
}

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.ProfileLocal;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import org.json.JSONArray;
import org.json.JSONException;
@ -40,6 +41,15 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface {
private static final String DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]";
public boolean isEdited() {
return edited;
}
public void setEdited(boolean edited) {
this.edited = edited;
}
boolean edited;
boolean mgdl;
boolean mmol;
Double dia;
@ -59,7 +69,7 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface {
loadSettings();
}
public void storeSettings() {
public synchronized void storeSettings() {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean(LOCAL_PROFILE + "mmol", mmol);
@ -72,12 +82,13 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface {
editor.putString(LOCAL_PROFILE + "targethigh", targetHigh.toString());
editor.apply();
createConvertedProfile();
createAndStoreConvertedProfile();
edited = false;
if (Config.logPrefsChange)
log.debug("Storing settings: " + getRawProfile().getData().toString());
}
public void loadSettings() {
public synchronized void loadSettings() {
if (Config.logPrefsChange)
log.debug("Loading stored settings");
@ -124,6 +135,8 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface {
} catch (JSONException ignored) {
}
}
edited = false;
createAndStoreConvertedProfile();
}
/*
@ -164,7 +177,16 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface {
"created_at": "2016-06-16T08:34:41.256Z"
}
*/
private void createConvertedProfile() {
private void createAndStoreConvertedProfile() {
convertedProfile = createProfileStore();
}
public synchronized boolean isValidEditState() {
return createProfileStore().getDefaultProfile().isValid(MainApp.gs(R.string.localprofile));
}
@NonNull
public ProfileStore createProfileStore() {
JSONObject json = new JSONObject();
JSONObject store = new JSONObject();
JSONObject profile = new JSONObject();
@ -183,21 +205,17 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface {
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
convertedProfile = new ProfileStore(json);
return new ProfileStore(json);
}
@Override
public ProfileStore getProfile() {
if (convertedProfile == null)
createConvertedProfile();
if (!convertedProfile.getDefaultProfile().isValid(MainApp.gs(R.string.localprofile)))
return null;
return convertedProfile;
}
public ProfileStore getRawProfile() {
if (convertedProfile == null)
createConvertedProfile();
return convertedProfile;
}
@ -208,8 +226,6 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface {
@Override
public String getProfileName() {
if (convertedProfile == null)
createConvertedProfile();
return DecimalFormatter.to2Decimal(convertedProfile.getDefaultProfile().percentageBasalSum()) + "U ";
}

View file

@ -1,52 +0,0 @@
package info.nightscout.androidaps.plugins.PumpCombo;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.text.DateFormat;
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpAlert;
import info.nightscout.androidaps.R;
public class ComboAlertHistoryDialog extends DialogFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.combo_alert_history_fragment, container, false);
TextView text = (TextView) layout.findViewById(R.id.combo_error_history_text);
List<PumpAlert> errors = ComboPlugin.getPlugin().getPump().errorHistory;
if (errors.isEmpty()) {
text.setText(R.string.combo_no_alert_data_note);
} else {
StringBuilder sb = new StringBuilder();
DateFormat dateTimeFormatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
boolean first = true;
for (PumpAlert error : errors) {
if (first) {
first = false;
} else {
sb.append("\n");
}
sb.append(dateTimeFormatter.format(error.timestamp));
sb.append(" ");
sb.append(error.message);
if (error.warningCode != null) {
sb.append(" (W");
sb.append(error.warningCode);
sb.append(")");
}
if (error.errorCode != null) {
sb.append(" (E");
sb.append(error.errorCode);
sb.append(")");
}
}
text.setText(sb.toString());
}
return layout;
}
}

View file

@ -6,6 +6,7 @@ import android.app.AlertDialog;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -16,7 +17,6 @@ import com.squareup.otto.Subscribe;
import org.apache.commons.lang3.StringUtils;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.PumpState;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Bolus;
import info.nightscout.androidaps.MainApp;
@ -29,7 +29,7 @@ import info.nightscout.androidaps.queue.events.EventQueueChanged;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.SP;
public class ComboFragment extends SubscriberFragment implements View.OnClickListener, View.OnLongClickListener {
public class ComboFragment extends SubscriberFragment implements View.OnClickListener {
private TextView stateView;
private TextView activityView;
private TextView batteryView;
@ -39,43 +39,28 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
private TextView baseBasalRate;
private TextView tempBasalText;
private Button refreshButton;
private Button alertsButton;
private Button tddsButton;
private TextView bolusCount;
private TextView tbrCount;
private Button fullHistoryButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.combopump_fragment, container, false);
stateView = (TextView) view.findViewById(R.id.combo_state);
activityView = (TextView) view.findViewById(R.id.combo_activity);
batteryView = (TextView) view.findViewById(R.id.combo_pumpstate_battery);
reservoirView = (TextView) view.findViewById(R.id.combo_insulinstate);
lastBolusView = (TextView) view.findViewById(R.id.combo_last_bolus);
lastConnectionView = (TextView) view.findViewById(R.id.combo_lastconnection);
baseBasalRate = (TextView) view.findViewById(R.id.combo_base_basal_rate);
tempBasalText = (TextView) view.findViewById(R.id.combo_temp_basal);
bolusCount = (TextView) view.findViewById(R.id.combo_bolus_count);
tbrCount = (TextView) view.findViewById(R.id.combo_tbr_count);
stateView = view.findViewById(R.id.combo_state);
activityView = view.findViewById(R.id.combo_activity);
batteryView = view.findViewById(R.id.combo_pumpstate_battery);
reservoirView = view.findViewById(R.id.combo_insulinstate);
lastBolusView = view.findViewById(R.id.combo_last_bolus);
lastConnectionView = view.findViewById(R.id.combo_lastconnection);
baseBasalRate = view.findViewById(R.id.combo_base_basal_rate);
tempBasalText = view.findViewById(R.id.combo_temp_basal);
bolusCount = view.findViewById(R.id.combo_bolus_count);
tbrCount = view.findViewById(R.id.combo_tbr_count);
refreshButton = (Button) view.findViewById(R.id.combo_refresh_button);
refreshButton = view.findViewById(R.id.combo_refresh_button);
refreshButton.setOnClickListener(this);
alertsButton = (Button) view.findViewById(R.id.combo_alerts_button);
alertsButton.setOnClickListener(this);
alertsButton.setOnLongClickListener(this);
tddsButton = (Button) view.findViewById(R.id.combo_tdds_button);
tddsButton.setOnClickListener(this);
tddsButton.setOnLongClickListener(this);
fullHistoryButton = (Button) view.findViewById(R.id.combo_full_history_button);
fullHistoryButton.setOnClickListener(this);
fullHistoryButton.setOnLongClickListener(this);
updateGUI();
return view;
}
@ -99,75 +84,9 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
}
});
break;
case R.id.combo_alerts_button:
ComboAlertHistoryDialog ehd = new ComboAlertHistoryDialog();
ehd.show(getFragmentManager(), ComboAlertHistoryDialog.class.getSimpleName());
break;
case R.id.combo_tdds_button:
ComboTddHistoryDialog thd = new ComboTddHistoryDialog();
thd.show(getFragmentManager(), ComboTddHistoryDialog.class.getSimpleName());
break;
case R.id.combo_full_history_button:
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setMessage(R.string.combo_read_full_history_info);
builder.show();
break;
}
}
// TODO clean up when when queuing
@Override
public boolean onLongClick(View view) {
switch (view.getId()) {
case R.id.combo_alerts_button:
alertsButton.setEnabled(false);
tddsButton.setEnabled(false);
fullHistoryButton.setEnabled(false);
new Thread(() -> ComboPlugin.getPlugin().readAlertData(new Callback() {
@Override
public void run() {
runOnUiThread(() -> {
alertsButton.setEnabled(true);
tddsButton.setEnabled(true);
fullHistoryButton.setEnabled(true);
});
}
})).start();
return true;
case R.id.combo_tdds_button:
alertsButton.setEnabled(false);
tddsButton.setEnabled(false);
fullHistoryButton.setEnabled(false);
new Thread(() -> ComboPlugin.getPlugin().readTddData(new Callback() {
@Override
public void run() {
runOnUiThread(() -> {
alertsButton.setEnabled(true);
tddsButton.setEnabled(true);
fullHistoryButton.setEnabled(true);
});
}
})).start();
return true;
case R.id.combo_full_history_button:
alertsButton.setEnabled(false);
tddsButton.setEnabled(false);
fullHistoryButton.setEnabled(false);
new Thread(() -> ComboPlugin.getPlugin().readAllPumpData(new Callback() {
@Override
public void run() {
runOnUiThread(() -> {
alertsButton.setEnabled(true);
tddsButton.setEnabled(true);
fullHistoryButton.setEnabled(true);
});
}
})).start();
return true;
}
return false;
}
@Subscribe
public void onStatusEvent(final EventComboPumpUpdateGUI ignored) {
updateGUI();
@ -210,13 +129,6 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
}
if (plugin.isInitialized()) {
refreshButton.setVisibility(View.VISIBLE);
if (Config.enableComboBetaFeatures) {
alertsButton.setVisibility(View.VISIBLE);
tddsButton.setVisibility(View.VISIBLE);
}
fullHistoryButton.setVisibility(View.VISIBLE);
// battery
batteryView.setTextSize(20);
if (ps.batteryState == PumpState.EMPTY) {

View file

@ -28,7 +28,7 @@ import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TDD;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.Constraint;
@ -68,8 +68,8 @@ import info.nightscout.utils.SP;
*/
public class ComboPlugin extends PluginBase implements PumpInterface, ConstraintsInterface {
private static final Logger log = LoggerFactory.getLogger(ComboPlugin.class);
public static final String COMBO_TBRS_SET = "combo_tbrs_set";
public static final String COMBO_BOLUSES_DELIVERED = "combo_boluses_delivered";
static final String COMBO_TBRS_SET = "combo_tbrs_set";
static final String COMBO_BOLUSES_DELIVERED = "combo_boluses_delivered";
private static ComboPlugin plugin = null;
@ -112,6 +112,9 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
pumpDescription.storesCarbInfo = false;
pumpDescription.is30minBasalRatesCapable = false;
pumpDescription.supportsTDDs = true;
pumpDescription.needsManualTDDLoad = true;
}
@NonNull
@ -1124,11 +1127,11 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
*/
private boolean readHistory(@Nullable PumpHistoryRequest request) {
CommandResult historyResult = runCommand(MainApp.gs(R.string.combo_activity_reading_pump_history), 3, () -> ruffyScripter.readHistory(request));
if (!historyResult.success) {
PumpHistory history = historyResult.history;
if (!historyResult.success || history == null) {
return false;
}
PumpHistory history = historyResult.history;
updateDbFromPumpHistory(history);
// update local cache
@ -1171,64 +1174,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
return pumpBolus.timestamp + Math.min(secondsFromBolus, 59 * 1000);
}
// TODO use queue once ready
void readTddData(Callback post) {
// ConfigBuilderPlugin.getCommandQueue().custom(new Callback() {
// @Override
// public void run() {
readHistory(new PumpHistoryRequest().tddHistory(PumpHistoryRequest.FULL));
// }
// }, post);
if (post != null) {
post.run();
}
CommandQueue commandQueue = ConfigBuilderPlugin.getCommandQueue();
if (commandQueue.performing() == null && commandQueue.size() == 0) {
ruffyScripter.disconnect();
}
}
// TODO use queue once ready
void readAlertData(Callback post) {
// ConfigBuilderPlugin.getCommandQueue().custom(new Callback() {
// @Override
// public void run() {
readHistory(new PumpHistoryRequest().pumpErrorHistory(PumpHistoryRequest.FULL));
// }
// }, post);
if (post != null) {
post.run();
}
CommandQueue commandQueue = ConfigBuilderPlugin.getCommandQueue();
if (commandQueue.performing() == null && commandQueue.size() == 0) {
ruffyScripter.disconnect();
}
}
// TODO use queue once ready
void readAllPumpData(Callback post) {
// ConfigBuilderPlugin.getCommandQueue().custom(new Callback() {
// @Override
// public void run() {
readHistory(new PumpHistoryRequest()
.bolusHistory(PumpHistoryRequest.FULL)
.pumpErrorHistory(PumpHistoryRequest.FULL)
.tddHistory(PumpHistoryRequest.FULL));
CommandResult readBasalResult = runCommand(MainApp.gs(R.string.combo_actvity_reading_basal_profile), 2, ruffyScripter::readBasalProfile);
if (readBasalResult.success) {
pump.basalProfile = readBasalResult.basalProfile;
}
// }
// }, post);
if (post != null) {
post.run();
}
CommandQueue commandQueue = ConfigBuilderPlugin.getCommandQueue();
if (commandQueue.performing() == null && commandQueue.size() == 0) {
ruffyScripter.disconnect();
}
}
/**
* Reads QuickInfo to update reservoir level and determine if new boluses exist on the pump
* and if so, queries the history for all new records.
@ -1378,7 +1323,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
@Override
public PumpEnactResult loadTDDs() {
PumpEnactResult result = new PumpEnactResult();
result.success = readHistory(new PumpHistoryRequest().tddHistory(PumpHistoryRequest.FULL));
if (result.success) {

View file

@ -1,58 +0,0 @@
package info.nightscout.androidaps.plugins.PumpCombo;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.text.DateFormat;
import java.util.List;
import java.util.Locale;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Tdd;
import info.nightscout.androidaps.R;
public class ComboTddHistoryDialog extends DialogFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.combo_tdd_history_fragment, container, false);
TextView text = (TextView) layout.findViewById(R.id.combo_tdd_history_text);
List<Tdd> tdds = ComboPlugin.getPlugin().getPump().tddHistory;
if (tdds.isEmpty()) {
text.setText(R.string.combo_no_tdd_data_note);
} else {
StringBuilder sb = new StringBuilder();
DateFormat dateFormatter = DateFormat.getDateInstance();
double avg = 0;
double min = 999;
double max = 0;
int count = 0;
for (Tdd tdd : tdds) {
if (tdd.total > 0) {
avg += tdd.total;
count++;
}
if (tdd.total < min) min = tdd.total;
if (tdd.total > max) max = tdd.total;
}
avg = avg / count;
sb.append(String.format(Locale.getDefault(), getString(R.string.combo_tdd_minimum), min));
sb.append("\n");
sb.append(String.format(Locale.getDefault(), getString(R.string.combo_tdd_average), avg));
sb.append("\n");
sb.append(String.format(Locale.getDefault(), getString(R.string.combo_tdd_maximum), max));
sb.append("\n");
for (Tdd tdd : tdds) {
sb.append("\n");
sb.append(dateFormatter.format(tdd.timestamp));
sb.append(" ");
sb.append(String.format(Locale.getDefault(), "%3.1f", tdd.total));
sb.append(" U");
}
text.setText(sb.toString());
}
return layout;
}
}

View file

@ -18,7 +18,7 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.Constraint;
@ -72,6 +72,9 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
pumpDescription.isRefillingCapable = true;
pumpDescription.storesCarbInfo = true;
pumpDescription.supportsTDDs = true;
pumpDescription.needsManualTDDLoad = true;
}
@Override

View file

@ -1,16 +1,12 @@
package info.nightscout.androidaps.plugins.PumpDanaR.comm;
import com.squareup.otto.Bus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
public class MsgBolusProgress extends MessageBase {

View file

@ -1,13 +1,11 @@
package info.nightscout.androidaps.plugins.PumpDanaR.comm;
import com.squareup.otto.Bus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
public class MsgBolusStop extends MessageBase {

View file

@ -21,10 +21,9 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventPumpStatusChanged;
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
import info.nightscout.androidaps.plugins.PumpDanaR.SerialIOThread;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStop;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryAlarm;

View file

@ -18,7 +18,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventPreferenceChange;

View file

@ -18,7 +18,7 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.Constraint;
@ -73,6 +73,9 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
pumpDescription.isRefillingCapable = true;
pumpDescription.storesCarbInfo = true;
pumpDescription.supportsTDDs = true;
pumpDescription.needsManualTDDLoad = true;
}
@Override

View file

@ -18,7 +18,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventPreferenceChange;

View file

@ -26,7 +26,7 @@ import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
@ -111,6 +111,9 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
pumpDescription.isRefillingCapable = true;
pumpDescription.storesCarbInfo = true;
pumpDescription.supportsTDDs = true;
pumpDescription.needsManualTDDLoad = true;
}
@Override
@ -363,9 +366,9 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
speed = 60;
break;
}
// v2 stores end time for bolus, we need to adjust time
// RS stores end time for bolus, we need to adjust time
// default delivery speed is 12 sec/U
detailedBolusInfo.date += detailedBolusInfo.insulin * speed * 1000;
detailedBolusInfo.date = DateUtil.now() + (long)(speed * detailedBolusInfo.insulin * 1000);
// clean carbs to prevent counting them as twice because they will picked up as another record
// I don't think it's necessary to copy DetailedBolusInfo right now for carbs records
double carbs = detailedBolusInfo.carbs;
@ -379,7 +382,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
t.isSMB = detailedBolusInfo.isSMB;
boolean connectionOK = false;
if (detailedBolusInfo.insulin > 0 || carbs > 0)
connectionOK = danaRSService.bolus(detailedBolusInfo.insulin, (int) carbs, System.currentTimeMillis() + carbTime * 60 * 1000, t);
connectionOK = danaRSService.bolus(detailedBolusInfo.insulin, (int) carbs, DateUtil.now() + carbTime * 60 * 1000, t);
PumpEnactResult result = new PumpEnactResult();
result.success = connectionOK;
result.bolusDelivered = t.insulin;

View file

@ -9,7 +9,7 @@ import info.nightscout.androidaps.R;
import com.cozmo.danar.util.BleCommandUtil;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
public class DanaRS_Packet_Bolus_Set_Step_Bolus_Stop extends DanaRS_Packet {

View file

@ -9,7 +9,7 @@ import info.nightscout.androidaps.R;
import com.cozmo.danar.util.BleCommandUtil;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
public class DanaRS_Packet_Notify_Delivery_Complete extends DanaRS_Packet {

View file

@ -7,7 +7,7 @@ import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import com.cozmo.danar.util.BleCommandUtil;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
public class DanaRS_Packet_Notify_Delivery_Rate_Display extends DanaRS_Packet {

View file

@ -19,7 +19,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventPumpStatusChanged;
@ -71,8 +71,10 @@ import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Notify_D
import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Option_Get_Pump_Time;
import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Option_Set_Pump_Time;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.SP;
import info.nightscout.utils.T;
public class DanaRSService extends Service {
private static Logger log = LoggerFactory.getLogger(DanaRSService.class);
@ -145,8 +147,10 @@ public class DanaRSService extends Service {
bleComm.sendMessage(new DanaRS_Packet_Option_Get_Pump_Time());
long timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
log.debug("Pump time difference: " + timeDiff + " seconds");
if (Math.abs(timeDiff) > 10) {
bleComm.sendMessage(new DanaRS_Packet_Option_Set_Pump_Time(new Date()));
if (Math.abs(timeDiff) > 3) {
waitForWholeMinute(); // Dana can set only whole minute
// add 10sec to be sure we are over minute (will be cutted off anyway)
bleComm.sendMessage(new DanaRS_Packet_Option_Set_Pump_Time(new Date(DateUtil.now() + T.secs(10).msecs())));
bleComm.sendMessage(new DanaRS_Packet_Option_Get_Pump_Time());
timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
log.debug("Pump time difference: " + timeDiff + " seconds");
@ -458,4 +462,14 @@ public class DanaRSService extends Service {
log.debug("EventAppExit finished");
}
void waitForWholeMinute() {
while (true) {
long time = DateUtil.now();
long timeToWholeMinute = (60000 - time % 60000);
if (timeToWholeMinute > 59800 || timeToWholeMinute < 300)
break;
MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.waitingfortimesynchronization, (int)(timeToWholeMinute / 1000))));
SystemClock.sleep(Math.min(timeToWholeMinute, 100));
}
}
}

View file

@ -17,14 +17,15 @@ import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage;
import info.nightscout.androidaps.plugins.PumpDanaR.AbstractDanaRPlugin;
import info.nightscout.androidaps.plugins.PumpDanaRv2.services.DanaRv2ExecutionService;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.Round;
import info.nightscout.utils.SP;
@ -72,6 +73,9 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
pumpDescription.isRefillingCapable = true;
pumpDescription.storesCarbInfo = true;
pumpDescription.supportsTDDs = true;
pumpDescription.needsManualTDDLoad = true;
}
@Override
@ -153,7 +157,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
speed = 60;
break;
}
detailedBolusInfo.date += speed * detailedBolusInfo.insulin * 1000;
detailedBolusInfo.date = DateUtil.now() + (long)(speed * detailedBolusInfo.insulin * 1000);
// clean carbs to prevent counting them as twice because they will picked up as another record
// I don't think it's necessary to copy DetailedBolusInfo right now for carbs records
double carbs = detailedBolusInfo.carbs;
@ -167,7 +171,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
t.isSMB = detailedBolusInfo.isSMB;
boolean connectionOK = false;
if (detailedBolusInfo.insulin > 0 || carbs > 0)
connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, System.currentTimeMillis() + carbTime * 60 * 1000, t);
connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, DateUtil.now() + carbTime * 60 * 1000, t);
PumpEnactResult result = new PumpEnactResult();
result.success = connectionOK;
result.bolusDelivered = t.insulin;
@ -380,4 +384,5 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
public PumpEnactResult loadEvents() {
return sExecutionService.loadEvents();
}
}

View file

@ -18,7 +18,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventPreferenceChange;
@ -64,8 +64,10 @@ import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgSetHistoryEntry_v2
import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgStatusBolusExtended_v2;
import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgStatusTempBasal_v2;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.SP;
import info.nightscout.utils.T;
import info.nightscout.utils.ToastUtils;
public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
@ -198,8 +200,10 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
mSerialIOThread.sendMessage(new MsgSettingPumpTime());
long timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
log.debug("Pump time difference: " + timeDiff + " seconds");
if (Math.abs(timeDiff) > 10) {
mSerialIOThread.sendMessage(new MsgSetTime(new Date()));
if (Math.abs(timeDiff) > 3) {
waitForWholeMinute(); // Dana can set only whole minute
// add 10sec to be sure we are over minute (will be cutted off anyway)
mSerialIOThread.sendMessage(new MsgSetTime(new Date(DateUtil.now() + T.secs(10).msecs())));
mSerialIOThread.sendMessage(new MsgSettingPumpTime());
timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
log.debug("Pump time difference: " + timeDiff + " seconds");
@ -450,4 +454,14 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
return true;
}
void waitForWholeMinute() {
while (true) {
long time = DateUtil.now();
long timeToWholeMinute = (60000 - time % 60000);
if (timeToWholeMinute > 59800 || timeToWholeMinute < 3000)
break;
MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.waitingfortimesynchronization, (int)(timeToWholeMinute / 1000))));
SystemClock.sleep(Math.min(timeToWholeMinute, 100));
}
}
}

View file

@ -21,7 +21,7 @@ import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
@ -142,6 +142,9 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai
pumpDescription.isRefillingCapable = true;
pumpDescription.storesCarbInfo = false;
pumpDescription.supportsTDDs = true;
pumpDescription.needsManualTDDLoad = false;
}
@ -193,8 +196,8 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai
@Override
public PumpEnactResult loadTDDs() {
//TODO: read TDDs and store to DB
PumpEnactResult result = new PumpEnactResult();
result.success = true;
return result;
}
@ -242,7 +245,6 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai
// TODO review
if (!Config.NSCLIENT && !Config.G5UPLOADER)
NSUpload.uploadDeviceStatus();
lastDataTime = new Date();
}
@Override
@ -283,7 +285,6 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai
public void getPumpStatus() {
log("getPumpStatus");
lastDataTime = new Date();
if (Connector.get().isPumpConnected()) {
log("is connected.. requesting status");
final UUID uuid = aSyncTaskRunner(new StatusTaskRunner(connector.getServiceConnector()), "Status");
@ -439,7 +440,6 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai
updateGui();
connector.tryToGetPumpStatusAgain();
lastDataTime = new Date();
connector.requestHistorySync(30000);
if (result.success) while (true) {
@ -538,8 +538,6 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai
if (Config.logPumpComm)
log.debug("Setting temp basal absolute: " + pumpEnactResult.success);
lastDataTime = new Date();
updateGui();
connector.requestHistorySync(5000);
@ -621,7 +619,6 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai
TemporaryBasal tempStop = new TemporaryBasal().date(System.currentTimeMillis()).source(Source.USER);
TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempStop);
}
lastDataTime = new Date();
updateGui();
if (Config.logPumpComm)
log.debug("Canceling temp basal: "); // TODO get more info
@ -950,6 +947,7 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai
singleMessageTaskRunner.fetch(new TaskRunner.ResultCallback() {
@Override
public void onResult(Object o) {
lastDataTime = new Date();
log(name + " success");
event.response_object = o;
if (o instanceof BolusMessage) {
@ -988,6 +986,7 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai
task.fetch(new TaskRunner.ResultCallback() {
@Override
public void onResult(Object o) {
lastDataTime = new Date();
log(name + " success");
event.response_object = o;
event.success = true;

View file

@ -1,18 +1,25 @@
package info.nightscout.androidaps.plugins.PumpInsight.history;
import android.content.Intent;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.TDD;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.SP;
import org.json.JSONException;
import org.json.JSONObject;
import sugar.free.sightparser.handling.HistoryBroadcast;
import java.util.Date;
import sugar.free.sightparser.handling.HistoryBroadcast;
import static info.nightscout.androidaps.plugins.PumpInsight.history.PumpIdCache.updatePumpSerialNumber;
/**
* Created by jamorham on 27/01/2018.
*
* <p>
* Parse inbound logbook intents
*
*/
class HistoryIntentAdapter {
@ -109,4 +116,88 @@ class HistoryIntentAdapter {
log("ERROR, UNKNWON BOLUS TYPE: " + bolus_type);
}
}
void processDailyTotalIntent(Intent intent) {
Date date = getDateExtra(intent, HistoryBroadcast.EXTRA_TOTAL_DATE);
double basal = intent.getDoubleExtra(HistoryBroadcast.EXTRA_BASAL_TOTAL, 0D);
double bolus = intent.getDoubleExtra(HistoryBroadcast.EXTRA_BOLUS_TOTAL, 0D);
TDD tdd = new TDD(date.getTime(), bolus, basal, bolus + basal);
MainApp.getDbHelper().createOrUpdateTDD(tdd);
}
void processCannulaFilledIntent(Intent intent) {
Date date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME);
uploadCareportalEvent(date, CareportalEvent.SITECHANGE);
}
void processCartridgeInsertedIntent(Intent intent) {
Date date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME);
uploadCareportalEvent(date, CareportalEvent.INSULINCHANGE);
}
void processBatteryInsertedIntent(Intent intent) {
Date date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME);
uploadCareportalEvent(date, CareportalEvent.PUMPBATTERYCHANGE);
}
private void uploadCareportalEvent(Date date, String event) {
if (SP.getBoolean("insight_automatic_careportal_events", false)) {
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(date.getTime()) != null) return;
try {
JSONObject data = new JSONObject();
String enteredBy = SP.getString("careportal_enteredby", "");
if (!enteredBy.equals("")) data.put("enteredBy", enteredBy);
data.put("created_at", DateUtil.toISOString(date));
data.put("eventType", event);
NSUpload.uploadCareportalEntryToNS(data);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
void processOccurenceOfAlertIntent(Intent intent) {
if (SP.getBoolean("insight_automatic_careportal_events", false)) {
Date date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME);
String alertType = intent.getStringExtra(HistoryBroadcast.EXTRA_ALERT_TYPE);
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(date.getTime()) != null) return;
try {
JSONObject data = new JSONObject();
String enteredBy = SP.getString("careportal_enteredby", "");
if (!enteredBy.equals("")) data.put("enteredBy", enteredBy);
data.put("created_at", DateUtil.toISOString(date));
data.put("eventType", CareportalEvent.NOTE);
data.put("notes", MainApp.instance().getString(getAlertText(alertType)));
NSUpload.uploadCareportalEntryToNS(data);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private int getAlertText(String type) {
if (type.equals("Error6MechanicalError")) return R.string.alert_e6;
if (type.equals("Error7ElectronicError")) return R.string.alert_e7;
if (type.equals("Error10RewindError")) return R.string.alert_e10;
if (type.equals("Error13LanguageError")) return R.string.alert_e13;
if (type.equals("Maintenance20CartridgeNotInserted")) return R.string.alert_m20;
if (type.equals("Maintenance21CartridgeEmpty")) return R.string.alert_m21;
if (type.equals("Maintenance22BatteryEmpty")) return R.string.alert_m22;
if (type.equals("Maintenance23AutomaticOff")) return R.string.alert_m23;
if (type.equals("Maintenance24Occlusion")) return R.string.alert_m24;
if (type.equals("Maintenance25LoantimeOver")) return R.string.alert_m25;
if (type.equals("Maintenance26CartridgeChangeNotCompleted")) return R.string.alert_m26;
if (type.equals("Maintenance27DataDownloadFailed")) return R.string.alert_m27;
if (type.equals("Maintenance28PauseModeTimeout")) return R.string.alert_m28;
if (type.equals("Maintenance29BatteryTypeNotSet")) return R.string.alert_m29;
if (type.equals("Maintenance30CartridgeTypeNotSet")) return R.string.alert_m30;
if (type.equals("Warning31CartridgeLow")) return R.string.alert_w31;
if (type.equals("Warning32BatteryLow")) return R.string.alert_w32;
if (type.equals("Warning33InvalidDateTime")) return R.string.alert_w33;
if (type.equals("Warning34EndOfWarranty")) return R.string.alert_w34;
if (type.equals("Warning36TBRCancelled")) return R.string.alert_w36;
if (type.equals("Warning38BolusCancelled")) return R.string.alert_w38;
if (type.equals("Warning39LoantimeWarning")) return R.string.alert_w39;
return 0;
}
}

View file

@ -11,13 +11,7 @@ import info.nightscout.androidaps.R;
import static info.nightscout.androidaps.plugins.PumpInsight.history.HistoryReceiver.Status.BUSY;
import static info.nightscout.androidaps.plugins.PumpInsight.history.HistoryReceiver.Status.SYNCED;
import static info.nightscout.androidaps.plugins.PumpInsight.history.HistoryReceiver.Status.SYNCING;
import static sugar.free.sightparser.handling.HistoryBroadcast.ACTION_BOLUS_DELIVERED;
import static sugar.free.sightparser.handling.HistoryBroadcast.ACTION_BOLUS_PROGRAMMED;
import static sugar.free.sightparser.handling.HistoryBroadcast.ACTION_END_OF_TBR;
import static sugar.free.sightparser.handling.HistoryBroadcast.ACTION_PUMP_STATUS_CHANGED;
import static sugar.free.sightparser.handling.HistoryBroadcast.ACTION_STILL_SYNCING;
import static sugar.free.sightparser.handling.HistoryBroadcast.ACTION_SYNC_FINISHED;
import static sugar.free.sightparser.handling.HistoryBroadcast.ACTION_SYNC_STARTED;
import static sugar.free.sightparser.handling.HistoryBroadcast.*;
/**
* Created by jamorham on 27/01/2018.
@ -45,9 +39,14 @@ public class HistoryReceiver {
filter.addAction(ACTION_BOLUS_PROGRAMMED);
filter.addAction(ACTION_BOLUS_DELIVERED);
filter.addAction(ACTION_END_OF_TBR);
filter.addAction(ACTION_DAILY_TOTAL);
filter.addAction(ACTION_SYNC_STARTED);
filter.addAction(ACTION_STILL_SYNCING);
filter.addAction(ACTION_SYNC_FINISHED);
filter.addAction(ACTION_CANNULA_FILLED);
filter.addAction(ACTION_CARTRIDGE_INSERTED);
filter.addAction(ACTION_BATTERY_INSERTED);
filter.addAction(ACTION_OCCURENCE_OF_ALERT);
MainApp.instance().registerReceiver(historyReceiver, filter);
}
@ -79,7 +78,6 @@ public class HistoryReceiver {
}
switch (action) {
case ACTION_SYNC_STARTED:
status = SYNCING;
break;
@ -95,6 +93,21 @@ public class HistoryReceiver {
case ACTION_END_OF_TBR:
intentAdapter.processTBRIntent(intent);
break;
case ACTION_DAILY_TOTAL:
intentAdapter.processDailyTotalIntent(intent);
break;
case ACTION_CANNULA_FILLED:
intentAdapter.processCannulaFilledIntent(intent);
break;
case ACTION_CARTRIDGE_INSERTED:
intentAdapter.processCartridgeInsertedIntent(intent);
break;
case ACTION_BATTERY_INSERTED:
intentAdapter.processBatteryInsertedIntent(intent);
break;
case ACTION_OCCURENCE_OF_ALERT:
intentAdapter.processOccurenceOfAlertIntent(intent);
break;
}
}
};

View file

@ -30,7 +30,7 @@ import info.nightscout.utils.SafeParse;
* Created by mike on 24.06.2017.
*/
public class SensitivityAAPSPlugin extends PluginBase implements SensitivityInterface{
public class SensitivityAAPSPlugin extends PluginBase implements SensitivityInterface {
private static Logger log = LoggerFactory.getLogger(SensitivityAAPSPlugin.class);
static SensitivityAAPSPlugin plugin = null;
@ -118,7 +118,9 @@ public class SensitivityAAPSPlugin extends PluginBase implements SensitivityInte
String ratioLimit = "";
String sensResult = "";
if (Config.logAutosensData)
log.debug("Records: " + index + " " + pastSensitivity);
Arrays.sort(deviations);
double percentile = IobCobCalculatorPlugin.percentile(deviations, 0.50);
@ -133,6 +135,7 @@ public class SensitivityAAPSPlugin extends PluginBase implements SensitivityInte
sensResult = "Sensitivity normal";
}
if (Config.logAutosensData)
log.debug(sensResult);
double rawRatio = ratio;

View file

@ -118,11 +118,14 @@ public class SensitivityOref0Plugin extends PluginBase implements SensitivityInt
String ratioLimit = "";
String sensResult = "";
if (Config.logAutosensData)
log.debug("Records: " + index + " " + pastSensitivity);
Arrays.sort(deviations);
for (double i = 0.9; i > 0.1; i = i - 0.02) {
if (IobCobCalculatorPlugin.percentile(deviations, (i + 0.02)) >= 0 && IobCobCalculatorPlugin.percentile(deviations, i) < 0) {
if (Config.logAutosensData)
log.debug(Math.round(100 * i) + "% of non-meal deviations negative (target 45%-50%)");
}
}
@ -140,7 +143,10 @@ public class SensitivityOref0Plugin extends PluginBase implements SensitivityInt
} else {
sensResult = "Sensitivity normal";
}
if (Config.logAutosensData)
log.debug(sensResult);
ratio = 1 + (basalOff / profile.getMaxDailyBasal());
double rawRatio = ratio;

View file

@ -315,7 +315,7 @@ public class SmsCommunicatorPlugin extends PluginBase {
switch (splited[1].toUpperCase()) {
case "REFRESH":
Intent restartNSClient = new Intent(Intents.ACTION_RESTART);
MainApp.getDbHelper().resetTreatments();
TreatmentsPlugin.getPlugin().getService().resetTreatments();
MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient);
List<ResolveInfo> q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0);
reply = "TERATMENTS REFRESH " + q.size() + " receivers";

View file

@ -1,10 +1,12 @@
package info.nightscout.androidaps.db;
package info.nightscout.androidaps.plugins.Treatments;
import android.graphics.Color;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -14,6 +16,8 @@ import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Iob;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.InsulinInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
@ -21,11 +25,14 @@ import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWith
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.JsonHelper;
@DatabaseTable(tableName = DatabaseHelper.DATABASE_TREATMENTS)
@DatabaseTable(tableName = Treatment.TABLE_TREATMENTS)
public class Treatment implements DataPointWithLabelInterface {
private static Logger log = LoggerFactory.getLogger(Treatment.class);
public static final String TABLE_TREATMENTS = "Treatments";
@DatabaseField(id = true)
public long date;
@ -57,6 +64,32 @@ public class Treatment implements DataPointWithLabelInterface {
public Treatment() {
}
public static Treatment createFromJson(JSONObject json) throws JSONException {
Treatment treatment = new Treatment();
treatment.source = Source.NIGHTSCOUT;
treatment.date = DateUtil.roundDateToSec(JsonHelper.safeGetLong(json, "mills"));
if (treatment.date == 0L)
return null;
treatment.carbs = JsonHelper.safeGetDouble(json,"carbs");
treatment.insulin = JsonHelper.safeGetDouble(json,"insulin");
treatment.pumpId = JsonHelper.safeGetLong(json, "pumpId");
treatment._id = json.getString("_id");
treatment.isSMB = JsonHelper.safeGetBoolean(json,"isSMB");
if (json.has("eventType")) {
treatment.mealBolus = !json.get("eventType").equals("Correction Bolus");
double carbs = treatment.carbs;
if (json.has("boluscalc")) {
JSONObject boluscalc = json.getJSONObject("boluscalc");
if (boluscalc.has("carbs")) {
carbs = Math.max(boluscalc.getDouble("carbs"), carbs);
}
}
if (carbs <= 0)
treatment.mealBolus = false;
}
return treatment;
}
public String toString() {
return "Treatment{" +
"date= " + date +
@ -72,9 +105,8 @@ public class Treatment implements DataPointWithLabelInterface {
}
public boolean isDataChanging(Treatment other) {
if (date != other.date) {
if (date != other.date)
return true;
}
if (insulin != other.insulin)
return true;
if (carbs != other.carbs)
@ -83,9 +115,8 @@ public class Treatment implements DataPointWithLabelInterface {
}
public boolean isEqual(Treatment other) {
if (date != other.date) {
if (date != other.date)
return false;
}
if (insulin != other.insulin)
return false;
if (carbs != other.carbs)

View file

@ -0,0 +1,426 @@
package info.nightscout.androidaps.plugins.Treatments;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import com.j256.ormlite.android.apptools.OpenHelperManager;
import com.j256.ormlite.android.apptools.OrmLiteBaseService;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.stmt.PreparedQuery;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.Where;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import com.squareup.otto.Subscribe;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.ICallback;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.events.EventNsTreatment;
import info.nightscout.androidaps.events.EventReloadTreatmentData;
import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
import info.nightscout.utils.JsonHelper;
/**
* Created by mike on 24.09.2017.
*/
public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
private static Logger log = LoggerFactory.getLogger(TreatmentService.class);
private static final ScheduledExecutorService treatmentEventWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledTreatmentEventPost = null;
public TreatmentService() {
onCreate();
dbInitialize();
MainApp.bus().register(this);
}
/**
* This method is a simple re-implementation of the database create and up/downgrade functionality
* in SQLiteOpenHelper#getDatabaseLocked method.
* <p>
* It is implemented to be able to late initialize separate plugins of the application.
*/
protected void dbInitialize() {
DatabaseHelper helper = OpenHelperManager.getHelper(this, DatabaseHelper.class);
int newVersion = helper.getNewVersion();
int oldVersion = helper.getOldVersion();
if (oldVersion > newVersion) {
onDowngrade(this.getConnectionSource(), oldVersion, newVersion);
} else {
onUpgrade(this.getConnectionSource(), oldVersion, newVersion);
}
}
public Dao<Treatment, Long> getDao() {
try {
return DaoManager.createDao(this.getConnectionSource(), Treatment.class);
} catch (SQLException e) {
log.error("Cannot create Dao for Treatment.class");
}
return null;
}
@Subscribe
@SuppressWarnings("unused")
public void handleNsEvent(EventNsTreatment event) {
int mode = event.getMode();
JSONObject payload = event.getPayload();
if (mode == EventNsTreatment.ADD || mode == EventNsTreatment.UPDATE) {
this.createTreatmentFromJsonIfNotExists(payload);
} else { // EventNsTreatment.REMOVE
this.deleteNS(payload);
}
}
@Override
public void onCreate() {
super.onCreate();
try {
log.info("onCreate");
TableUtils.createTableIfNotExists(this.getConnectionSource(), Treatment.class);
} catch (SQLException e) {
log.error("Can't create database", e);
throw new RuntimeException(e);
}
}
public void onUpgrade(ConnectionSource connectionSource, int oldVersion, int newVersion) {
if (oldVersion == 7 && newVersion == 8) {
log.debug("Upgrading database from v7 to v8");
try {
TableUtils.dropTable(connectionSource, Treatment.class, true);
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
} catch (SQLException e) {
log.error("Can't create database", e);
throw new RuntimeException(e);
}
} else {
log.info("onUpgrade");
// this.resetFood();
}
}
public void onDowngrade(ConnectionSource connectionSource, int oldVersion, int newVersion) {
// this method is not supported right now
}
public void resetTreatments() {
try {
TableUtils.dropTable(this.getConnectionSource(), Treatment.class, true);
TableUtils.createTableIfNotExists(this.getConnectionSource(), Treatment.class);
DatabaseHelper.updateEarliestDataChange(0);
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
scheduleTreatmentChange(null);
}
/**
* A place to centrally register events to be posted, if any data changed.
* This should be implemented in an abstract service-class.
* <p>
* We do need to make sure, that ICallback is extended to be able to handle multiple
* events, or handle a list of events.
* <p>
* on some methods the earliestDataChange event is handled separatly, in that it is checked if it is
* set to null by another event already (eg. scheduleExtendedBolusChange).
*
* @param event
* @param eventWorker
* @param callback
*/
private void scheduleEvent(final Event event, ScheduledExecutorService eventWorker,
final ICallback callback) {
class PostRunnable implements Runnable {
public void run() {
log.debug("Firing EventFoodChange");
MainApp.bus().post(event);
if (DatabaseHelper.earliestDataChange != null)
MainApp.bus().post(new EventNewHistoryData(DatabaseHelper.earliestDataChange));
DatabaseHelper.earliestDataChange = null;
callback.setPost(null);
}
}
// prepare task for execution in 1 sec
// cancel waiting task to prevent sending multiple posts
if (callback.getPost() != null)
callback.getPost().cancel(false);
Runnable task = new PostRunnable();
final int sec = 1;
callback.setPost(eventWorker.schedule(task, sec, TimeUnit.SECONDS));
}
/**
* 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;
}
@Override
public ScheduledFuture<?> getPost() {
return scheduledTreatmentEventPost;
}
});
}
public List<Treatment> getTreatmentData() {
try {
return this.getDao().queryForAll();
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<>();
}
/*
{
"_id": "551ee3ad368e06e80856e6a9",
"type": "food",
"category": "Zakladni",
"subcategory": "Napoje",
"name": "Mleko",
"portion": 250,
"carbs": 12,
"gi": 1,
"created_at": "2015-04-14T06:59:16.500Z",
"unit": "ml"
}
*/
public void createTreatmentFromJsonIfNotExists(JSONObject json) {
try {
Treatment treatment = Treatment.createFromJson(json);
if (treatment != null)
createOrUpdate(treatment);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
public void createFoodFromJsonIfNotExists(JSONArray array) {
try {
for (int n = 0; n < array.length(); n++) {
JSONObject json = array.getJSONObject(n);
createTreatmentFromJsonIfNotExists(json);
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
// return true if new record is created
public boolean createOrUpdate(Treatment treatment) {
try {
Treatment old;
treatment.date = DatabaseHelper.roundDateToSec(treatment.date);
if (treatment.source == Source.PUMP) {
// check for changed from pump change in NS
QueryBuilder<Treatment, Long> queryBuilder = getDao().queryBuilder();
Where where = queryBuilder.where();
where.eq("pumpId", treatment.pumpId);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
List<Treatment> trList = getDao().query(preparedQuery);
if (trList.size() > 0) {
// do nothing, pump history record cannot be changed
log.debug("TREATMENT: Pump record already found in database: " + treatment.toString());
return false;
}
getDao().create(treatment);
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
DatabaseHelper.updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
return true;
}
if (treatment.source == Source.NIGHTSCOUT) {
old = getDao().queryForId(treatment.date);
if (old != null) {
if (!old.isEqual(treatment)) {
boolean historyChange = old.isDataChanging(treatment);
long oldDate = old.date;
getDao().delete(old); // need to delete/create because date may change too
old.copyFrom(treatment);
getDao().create(old);
log.debug("TREATMENT: Updating record by date from: " + Source.getString(treatment.source) + " " + old.toString());
if (historyChange) {
DatabaseHelper.updateEarliestDataChange(oldDate);
DatabaseHelper.updateEarliestDataChange(old.date);
}
scheduleTreatmentChange(treatment);
return true;
}
return false;
}
// find by NS _id
if (treatment._id != null) {
old = findByNSId(treatment._id);
if (old != null) {
if (!old.isEqual(treatment)) {
boolean historyChange = old.isDataChanging(treatment);
long oldDate = old.date;
getDao().delete(old); // need to delete/create because date may change too
old.copyFrom(treatment);
getDao().create(old);
log.debug("TREATMENT: Updating record by _id from: " + Source.getString(treatment.source) + " " + old.toString());
if (historyChange) {
DatabaseHelper.updateEarliestDataChange(oldDate);
DatabaseHelper.updateEarliestDataChange(old.date);
}
scheduleTreatmentChange(treatment);
return true;
}
}
}
getDao().create(treatment);
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
DatabaseHelper.updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
return true;
}
if (treatment.source == Source.USER) {
getDao().create(treatment);
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
DatabaseHelper.updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
return true;
}
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return false;
}
public void deleteNS(JSONObject json) {
String _id = JsonHelper.safeGetString(json, "_id");
if (_id != null && !_id.isEmpty())
this.deleteByNSId(_id);
}
/**
* deletes an entry by its NS Id.
* <p>
* Basically a convenience method for findByNSId and delete.
*
* @param _id
*/
private void deleteByNSId(String _id) {
Treatment stored = findByNSId(_id);
if (stored != null) {
log.debug("TREATMENT: Removing Treatment record from database: " + stored.toString());
delete(stored);
DatabaseHelper.updateEarliestDataChange(stored.date);
scheduleTreatmentChange(null);
}
}
/**
* deletes the treatment and sends the treatmentChange Event
* <p>
* should be moved ot a Service
*
* @param treatment
*/
public void delete(Treatment treatment) {
try {
getDao().delete(treatment);
DatabaseHelper.updateEarliestDataChange(treatment.date);
this.scheduleTreatmentChange(treatment);
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
}
public void update(Treatment treatment) {
try {
getDao().update(treatment);
DatabaseHelper.updateEarliestDataChange(treatment.date);
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
scheduleTreatmentChange(treatment);
}
/**
* finds treatment by its NS Id.
*
* @param _id
* @return
*/
@Nullable
public Treatment findByNSId(String _id) {
try {
Dao<Treatment, Long> daoTreatments = getDao();
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
Where where = queryBuilder.where();
where.eq("_id", _id);
queryBuilder.limit(10L);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
List<Treatment> trList = daoTreatments.query(preparedQuery);
if (trList.size() != 1) {
//log.debug("Treatment findTreatmentById query size: " + trList.size());
return null;
} else {
//log.debug("Treatment findTreatmentById found: " + trList.get(0).log());
return trList.get(0);
}
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return null;
}
public List<Treatment> getTreatmentDataFromTime(long mills, boolean ascending) {
try {
Dao<Treatment, Long> daoTreatments = getDao();
List<Treatment> treatments;
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.ge("date", mills);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
treatments = daoTreatments.query(preparedQuery);
return treatments;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<>();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

View file

@ -27,7 +27,6 @@ import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventReloadProfileSwitchData;
import info.nightscout.androidaps.events.EventReloadTempBasalData;
import info.nightscout.androidaps.events.EventReloadTreatmentData;
@ -41,8 +40,10 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.SP;
import info.nightscout.utils.T;
/**
* Created by mike on 05.08.2016.
@ -58,14 +59,16 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
return treatmentsPlugin;
}
private TreatmentService service;
private IobTotal lastTreatmentCalculation;
private IobTotal lastTempBasalsCalculation;
private final static ArrayList<Treatment> treatments = new ArrayList<>();
private final static Intervals<TemporaryBasal> tempBasals = new NonOverlappingIntervals<>();
private final static Intervals<ExtendedBolus> extendedBoluses = new NonOverlappingIntervals<>();
private final static Intervals<TempTarget> tempTargets = new OverlappingIntervals<>();
private final static ProfileIntervals<ProfileSwitch> profiles = new ProfileIntervals<>();
private final ArrayList<Treatment> treatments = new ArrayList<>();
private final Intervals<TemporaryBasal> tempBasals = new NonOverlappingIntervals<>();
private final Intervals<ExtendedBolus> extendedBoluses = new NonOverlappingIntervals<>();
private final Intervals<TempTarget> tempTargets = new OverlappingIntervals<>();
private final ProfileIntervals<ProfileSwitch> profiles = new ProfileIntervals<>();
public TreatmentsPlugin() {
super(new PluginDescription()
@ -76,6 +79,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
.preferencesId(R.xml.pref_absorption_oref0)
.alwaysEnabled(true)
);
this.service = new TreatmentService();
}
@Override
@ -94,18 +98,22 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
MainApp.bus().register(this);
}
private static void initializeTreatmentData() {
public TreatmentService getService() {
return this.service;
}
private void initializeTreatmentData() {
double dia = Constants.defaultDIA;
if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null)
dia = MainApp.getConfigBuilder().getProfile().getDia();
long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
synchronized (treatments) {
treatments.clear();
treatments.addAll(MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false));
treatments.addAll(getService().getTreatmentDataFromTime(fromMills, false));
}
}
private static void initializeTempBasalData() {
private void initializeTempBasalData() {
double dia = Constants.defaultDIA;
if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null)
dia = MainApp.getConfigBuilder().getProfile().getDia();
@ -117,7 +125,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
}
private static void initializeExtendedBolusData() {
private void initializeExtendedBolusData() {
double dia = Constants.defaultDIA;
if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null)
dia = MainApp.getConfigBuilder().getProfile().getDia();
@ -203,7 +211,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
if (profile == null) return result;
long now = System.currentTimeMillis();
long dia_ago = now - (Double.valueOf(1.5d * profile.getDia() * 60 * 60 * 1000l)).longValue();
long dia_ago = now - (Double.valueOf(1.5d * profile.getDia() * T.hours(1).msecs())).longValue();
synchronized (treatments) {
for (Treatment treatment : treatments) {
@ -235,7 +243,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
@Override
public List<Treatment> getTreatmentsFromHistory() {
synchronized (treatments) {
return (List<Treatment>) treatments.clone();
return new ArrayList<>(treatments);
}
}
@ -300,6 +308,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
}
@Subscribe
@SuppressWarnings("unused")
public void onStatusEvent(final EventReloadTempBasalData ev) {
log.debug("EventReloadTempBasalData");
initializeTempBasalData();
@ -312,22 +321,15 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
}
@Override
public IobTotal getCalculationToTimeTempBasals(long time) {
public IobTotal getCalculationToTimeTempBasals(long time, Profile profile) {
IobTotal total = new IobTotal(time);
synchronized (tempBasals) {
for (Integer pos = 0; pos < tempBasals.size(); pos++) {
TemporaryBasal t = tempBasals.get(pos);
if (t.date > time) continue;
IobTotal calc = t.iobCalc(time);
IobTotal calc = t.iobCalc(time, profile);
//log.debug("BasalIOB " + new Date(time) + " >>> " + calc.basaliob);
total.plus(calc);
if (!t.isEndingEvent()) {
total.lastTempDate = t.date;
total.lastTempDuration = t.durationInMinutes;
Profile profile = MainApp.getConfigBuilder().getProfile(t.date);
total.lastTempRate = t.tempBasalConvertedToAbsolute(t.date, profile);
}
}
}
if (ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses()) {
@ -338,13 +340,6 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
if (e.date > time) continue;
IobTotal calc = e.iobCalc(time);
totalExt.plus(calc);
TemporaryBasal t = new TemporaryBasal(e);
if (!t.isEndingEvent() && t.date > total.lastTempDate) {
total.lastTempDate = t.date;
total.lastTempDuration = t.durationInMinutes;
Profile profile = MainApp.getConfigBuilder().getProfile(t.date);
total.lastTempRate = t.tempBasalConvertedToAbsolute(t.date, profile);
}
}
}
// Convert to basal iob
@ -359,7 +354,9 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
@Override
public void updateTotalIOBTempBasals() {
lastTempBasalsCalculation = getCalculationToTimeTempBasals(System.currentTimeMillis());
Profile profile = MainApp.getConfigBuilder().getProfile();
if (profile != null)
lastTempBasalsCalculation = getCalculationToTimeTempBasals(DateUtil.now(), profile);
}
@Nullable
@ -442,7 +439,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
treatment.carbs = detailedBolusInfo.carbs;
treatment.source = detailedBolusInfo.source;
treatment.mealBolus = treatment.carbs > 0;
boolean newRecordCreated = MainApp.getDbHelper().createOrUpdate(treatment);
boolean newRecordCreated = getService().createOrUpdate(treatment);
//log.debug("Adding new Treatment record" + treatment.toString());
if (detailedBolusInfo.carbTime != 0) {
Treatment carbsTreatment = new Treatment();
@ -451,7 +448,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
carbsTreatment.date = detailedBolusInfo.date + detailedBolusInfo.carbTime * 60 * 1000L + 1000L; // add 1 sec to make them different records
carbsTreatment.carbs = detailedBolusInfo.carbs;
carbsTreatment.source = detailedBolusInfo.source;
MainApp.getDbHelper().createOrUpdate(carbsTreatment);
getService().createOrUpdate(carbsTreatment);
//log.debug("Adding new Treatment record" + carbsTreatment);
}
if (newRecordCreated && detailedBolusInfo.isValid)
@ -480,6 +477,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
// TempTargets
@Subscribe
@SuppressWarnings("unused")
public void onStatusEvent(final EventTempTargetChange ev) {
initializeTempTargetData();
}
@ -509,6 +507,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
// Profile Switch
@Subscribe
@SuppressWarnings("unused")
public void onStatusEvent(final EventReloadProfileSwitchData ev) {
initializeProfileSwitchData();
}

View file

@ -31,7 +31,7 @@ import info.nightscout.androidaps.Services.Intents;
import info.nightscout.androidaps.data.Iob;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
@ -145,14 +145,14 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
final String _id = treatment._id;
if (treatment.source == Source.PUMP) {
treatment.isValid = false;
MainApp.getDbHelper().update(treatment);
TreatmentsPlugin.getPlugin().getService().update(treatment);
} else {
if (NSUpload.isIdValid(_id)) {
NSUpload.removeCareportalEntryFromNS(_id);
} else {
UploadQueue.removeID("dbAdd", _id);
}
MainApp.getDbHelper().delete(treatment);
TreatmentsPlugin.getPlugin().getService().delete(treatment);
}
updateGUI();
FabricPrivacy.getInstance().logCustom(new CustomEvent("RemoveTreatment"));
@ -204,7 +204,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
builder.setMessage(this.getContext().getString(R.string.refresheventsfromnightscout) + "?");
builder.setPositiveButton(this.getContext().getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MainApp.getDbHelper().resetTreatments();
TreatmentsPlugin.getPlugin().getService().resetTreatments();
Intent restartNSClient = new Intent(Intents.ACTION_RESTART);
MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient);
}

View file

@ -2,9 +2,9 @@ package info.nightscout.androidaps.plugins.Treatments.fragments;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Paint;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.CardView;
@ -18,9 +18,6 @@ import android.widget.TextView;
import com.crashlytics.android.answers.CustomEvent;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Intervals;
@ -40,8 +37,6 @@ import info.nightscout.utils.NSUpload;
public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment {
private static Logger log = LoggerFactory.getLogger(TreatmentsTemporaryBasalsFragment.class);
RecyclerView recyclerView;
LinearLayoutManager llm;
@ -70,7 +65,7 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment {
holder.ns.setVisibility(NSUpload.isIdValid(tempBasal._id) ? View.VISIBLE : View.GONE);
if (tempBasal.isEndingEvent()) {
holder.date.setText(DateUtil.dateAndTimeString(tempBasal.date));
holder.duration.setText(MainApp.sResources.getString(R.string.cancel));
holder.duration.setText(MainApp.gs(R.string.cancel));
holder.absolute.setText("");
holder.percent.setText("");
holder.realDuration.setText("");
@ -82,14 +77,16 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment {
} else {
if (tempBasal.isInProgress()) {
holder.date.setText(DateUtil.dateAndTimeString(tempBasal.date));
holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive));
} else {
holder.date.setText(DateUtil.dateAndTimeString(tempBasal.date) + " - " + DateUtil.timeString(tempBasal.end()));
holder.date.setText(DateUtil.dateAndTimeRangeString(tempBasal.date, tempBasal.end()));
holder.date.setTextColor(holder.netRatio.getCurrentTextColor());
}
holder.duration.setText(DecimalFormatter.to0Decimal(tempBasal.durationInMinutes) + " min");
holder.duration.setText(DecimalFormatter.to0Decimal(tempBasal.durationInMinutes, " min"));
if (tempBasal.isAbsolute) {
Profile profile = MainApp.getConfigBuilder().getProfile(tempBasal.date);
if (profile != null) {
holder.absolute.setText(DecimalFormatter.to0Decimal(tempBasal.tempBasalConvertedToAbsolute(tempBasal.date, profile)) + " U/h");
holder.absolute.setText(DecimalFormatter.to0Decimal(tempBasal.tempBasalConvertedToAbsolute(tempBasal.date, profile), " U/h"));
holder.percent.setText("");
} else {
holder.absolute.setText(MainApp.gs(R.string.noprofile));
@ -97,24 +94,19 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment {
}
} else {
holder.absolute.setText("");
holder.percent.setText(DecimalFormatter.to0Decimal(tempBasal.percentRate) + "%");
holder.percent.setText(DecimalFormatter.to0Decimal(tempBasal.percentRate, "%"));
}
holder.realDuration.setText(DecimalFormatter.to0Decimal(tempBasal.getRealDuration()) + " min");
IobTotal iob = new IobTotal(System.currentTimeMillis());
try { // in case app loaded and still no profile selected
iob = tempBasal.iobCalc(System.currentTimeMillis());
} catch (Exception e) {
}
holder.iob.setText(DecimalFormatter.to2Decimal(iob.basaliob) + " U");
holder.netInsulin.setText(DecimalFormatter.to2Decimal(iob.netInsulin) + " U");
holder.netRatio.setText(DecimalFormatter.to2Decimal(iob.netRatio) + " U/h");
//holder.extendedFlag.setVisibility(tempBasal.isExtended ? View.VISIBLE : View.GONE);
holder.realDuration.setText(DecimalFormatter.to0Decimal(tempBasal.getRealDuration(), " min"));
long now = DateUtil.now();
IobTotal iob = new IobTotal(now);
Profile profile = MainApp.getConfigBuilder().getProfile(now);
if (profile != null)
iob = tempBasal.iobCalc(now, profile);
holder.iob.setText(DecimalFormatter.to2Decimal(iob.basaliob, " U"));
holder.netInsulin.setText(DecimalFormatter.to2Decimal(iob.netInsulin, " U"));
holder.netRatio.setText(DecimalFormatter.to2Decimal(iob.netRatio, " U/h"));
holder.extendedFlag.setVisibility(View.GONE);
if (tempBasal.isInProgress())
holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive));
else
holder.date.setTextColor(holder.netRatio.getCurrentTextColor());
if (tempBasal.iobCalc(System.currentTimeMillis()).basaliob != 0)
if (iob.basaliob != 0)
holder.iob.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive));
else
holder.iob.setTextColor(holder.netRatio.getCurrentTextColor());
@ -172,10 +164,9 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment {
switch (v.getId()) {
case R.id.tempbasals_remove:
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.sResources.getString(R.string.confirmation));
builder.setMessage(MainApp.sResources.getString(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(tempBasal.date));
builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(MainApp.gs(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(tempBasal.date));
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
final String _id = tempBasal._id;
if (NSUpload.isIdValid(_id)) {
NSUpload.removeCareportalEntryFromNS(_id);
@ -184,9 +175,8 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment {
}
MainApp.getDbHelper().delete(tempBasal);
FabricPrivacy.getInstance().logCustom(new CustomEvent("RemoveTempBasal"));
}
});
builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null);
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
break;
}
@ -195,7 +185,7 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.treatments_tempbasals_fragment, container, false);
@ -216,12 +206,12 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment {
}
@Subscribe
public void onStatusEvent(final EventTempBasalChange ev) {
public void onStatusEvent(final EventTempBasalChange ignored) {
updateGUI();
}
@Subscribe
public void onStatusEvent(final EventNewBG ev) {
public void onStatusEvent(final EventNewBG ignored) {
updateGUI();
}
@ -229,15 +219,11 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment {
protected void updateGUI() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.runOnUiThread(() -> {
recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTemporaryBasalsFromHistory()), false);
if (TreatmentsPlugin.getPlugin().getLastCalculationTempBasals() != null) {
String totalText = DecimalFormatter.to2Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().basaliob) + " U";
tempBasalTotalView.setText(totalText);
}
}
IobTotal tempBasalsCalculation = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals();
if (tempBasalsCalculation != null)
tempBasalTotalView.setText(DecimalFormatter.to2Decimal(tempBasalsCalculation.basaliob, " U"));
});
}

View file

@ -37,7 +37,7 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;

View file

@ -299,9 +299,10 @@ public class CommandQueue {
// returns true if command is queued
public boolean setProfile(Profile profile, Callback callback) {
if (isRunning(Command.CommandType.BASALPROFILE)) {
if (isThisProfileSet(profile)) {
log.debug("QUEUE: Correct profile already set");
if (callback != null)
callback.result(executingNowError()).run();
callback.result(new PumpEnactResult().success(true).enacted(false)).run();
return false;
}
@ -329,13 +330,6 @@ public class CommandQueue {
MainApp.bus().post(new EventDismissNotification(Notification.BASAL_VALUE_BELOW_MINIMUM));
if (isThisProfileSet(profile)) {
log.debug("QUEUE: Correct profile already set");
if (callback != null)
callback.result(new PumpEnactResult().success(true).enacted(false)).run();
return false;
}
// remove all unfinished
removeAll(Command.CommandType.BASALPROFILE);

View file

@ -1,5 +1,8 @@
package info.nightscout.androidaps.queue.commands;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
@ -17,6 +20,7 @@ import info.nightscout.androidaps.queue.Callback;
*/
public class CommandSetProfile extends Command {
private static Logger log = LoggerFactory.getLogger(CommandSetProfile.class);
private Profile profile;
public CommandSetProfile(Profile profile, Callback callback) {
@ -27,6 +31,13 @@ public class CommandSetProfile extends Command {
@Override
public void execute() {
if (ConfigBuilderPlugin.getCommandQueue().isThisProfileSet(profile)) {
log.debug("QUEUE: Correct profile already set");
if (callback != null)
callback.result(new PumpEnactResult().success(true).enacted(false)).run();
return;
}
PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setNewBasalProfile(profile);
if (callback != null)
callback.result(r).run();

View file

@ -122,6 +122,10 @@ public class DateUtil {
return dateString(date) + " " + timeString(date);
}
public static String dateAndTimeRangeString(long start, long end) {
return dateAndTimeString(start) + " - " + timeString(end);
}
public static String dateAndTimeString(long mills) {
return dateString(mills) + " " + timeString(mills);
}
@ -167,4 +171,8 @@ public class DateUtil {
return System.currentTimeMillis();
}
public static long roundDateToSec(long date) {
return date - date % 1000;
}
}

View file

@ -17,18 +17,34 @@ public class DecimalFormatter {
return format0dec.format(value);
}
public static String to0Decimal(double value, String unit) {
return format0dec.format(value) + unit;
}
public static String to1Decimal(double value) {
return format1dec.format(value);
}
public static String to1Decimal(double value, String unit) {
return format1dec.format(value) + unit;
}
public static String to2Decimal(double value) {
return format2dec.format(value);
}
public static String to2Decimal(double value, String unit) {
return format2dec.format(value) + unit;
}
public static String to3Decimal(double value) {
return format3dec.format(value);
}
public static String to3Decimal(double value, String unit) {
return format3dec.format(value) + unit;
}
public static String toPumpSupportedBolus(double value) {
return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.01
? to2Decimal(value)

View file

@ -17,41 +17,79 @@ public class JsonHelper {
private JsonHelper() {};
public static String safeGetString(JSONObject json, String fieldName) throws JSONException {
public static String safeGetString(JSONObject json, String fieldName) {
String result = null;
if (json.has(fieldName)) {
try {
result = json.getString(fieldName);
} catch (JSONException ignored) {
}
}
return result;
}
public static String safeGetString(JSONObject json, String fieldName, String defaultValue) throws JSONException {
public static String safeGetString(JSONObject json, String fieldName, String defaultValue) {
String result = defaultValue;
if (json.has(fieldName)) {
try {
result = json.getString(fieldName);
} catch (JSONException ignored) {
}
}
return result;
}
public static double safeGetDouble(JSONObject json, String fieldName) throws JSONException {
public static double safeGetDouble(JSONObject json, String fieldName) {
double result = 0d;
if (json.has(fieldName)) {
try {
result = json.getDouble(fieldName);
} catch (JSONException ignored) {
}
}
return result;
}
public static int safeGetInt(JSONObject json, String fieldName) throws JSONException {
public static int safeGetInt(JSONObject json, String fieldName) {
int result = 0;
if (json.has(fieldName)) {
try {
result = json.getInt(fieldName);
} catch (JSONException ignored) {
}
}
return result;
}
public static long safeGetLong(JSONObject json, String fieldName) {
long result = 0;
if (json.has(fieldName)) {
try {
result = json.getLong(fieldName);
} catch (JSONException e) {
}
}
return result;
}
public static boolean safeGetBoolean(JSONObject json, String fieldName) {
boolean result = false;
if (json.has(fieldName)) {
try {
result = json.getBoolean(fieldName);
} catch (JSONException e) {
}
}
return result;

View file

@ -406,6 +406,10 @@ public class NSUpload {
}
public static void uploadError(String error) {
uploadError(error, new Date());
}
public static void uploadError(String error, Date date) {
Context context = MainApp.instance().getApplicationContext();
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
@ -413,7 +417,7 @@ public class NSUpload {
JSONObject data = new JSONObject();
try {
data.put("eventType", "Announcement");
data.put("created_at", DateUtil.toISOString(new Date()));
data.put("created_at", DateUtil.toISOString(date));
data.put("enteredBy", SP.getString("careportal_enteredby", MainApp.gs(R.string.app_name)));
data.put("notes", error);
data.put("isAnnouncement", true);

View file

@ -148,6 +148,9 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener,
}
public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formater, boolean allowZero, TextWatcher textWatcher) {
if(this.textWatcher != null) {
editText.removeTextChangedListener(this.textWatcher);
}
setParams(initValue, minValue, maxValue, step, formater, allowZero);
this.textWatcher = textWatcher;
editText.addTextChangedListener(textWatcher);

View file

@ -78,6 +78,7 @@ public class TimeListEdit {
private void buildView() {
layout = (LinearLayout) view.findViewById(resLayoutId);
layout.removeAllViews();
textlabel = new TextView(context);
textlabel.setText(label);

View file

@ -1,53 +0,0 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".plugins.PumpCombo.ComboFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:layout_marginTop="5dp"
android:text="Alerts"
android:textStyle="bold" />
<View
android:id="@+id/profileview_datedelimiter"
android:layout_width="match_parent"
android:layout_height="2dip"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/combo_error_history_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="textStart"
android:padding="10dp"
android:gravity="start"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
</FrameLayout>

View file

@ -1,54 +0,0 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".plugins.PumpCombo.ComboFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:layout_marginTop="5dp"
android:text="@string/combo_tdds"
android:textStyle="bold" />
<View
android:id="@+id/profileview_datedelimiter"
android:layout_width="match_parent"
android:layout_height="2dip"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/combo_tdd_history_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:padding="10dp"
android:textAlignment="textStart" />
</LinearLayout>
</ScrollView>
</LinearLayout>
</FrameLayout>

View file

@ -499,46 +499,6 @@
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/combo_refresh" />
<info.nightscout.utils.SingleClickButton
android:id="@+id/combo_alerts_button"
style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:layout_marginRight="-4dp"
android:drawableTop="@drawable/icon_cp_announcement"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:visibility="gone"
android:text="@string/combo_pump_alerts" />
<info.nightscout.utils.SingleClickButton
android:id="@+id/combo_tdds_button"
style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:layout_marginRight="-4dp"
android:drawableTop="@drawable/icon_danarstats"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:visibility="gone"
android:text="@string/combo_tdds" />
<info.nightscout.utils.SingleClickButton
android:id="@+id/combo_full_history_button"
style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:layout_marginRight="-4dp"
android:drawableTop="@drawable/icon_danarhistory"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:visibility="gone"
android:text="@string/combo_history" />
</LinearLayout>
</LinearLayout>

View file

@ -153,6 +153,43 @@
android:text="@string/activate_profile"
android:textColor="@color/colorProfileSwitchButton" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal">
<Button
android:id="@+id/localprofile_reset"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="3dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:layout_weight="1"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/reset"
android:textColor="@color/colorProfileSwitchButton" />
<Button
android:id="@+id/localprofile_save"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="3dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:layout_weight="1"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/save"
android:textColor="@color/colorProfileSwitchButton" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View file

@ -678,9 +678,6 @@
<string name="shortenergy">En</string>
<string name="raise_notifications_as_android_notifications">Използвай системни известия за аларми и съобщения</string>
<string name="combo_warning">Внимание</string>
<string name="combo_tdd_minimum" formatted="false">Минимум: %3.1f U</string>
<string name="combo_tdd_maximum" formatted="false">Максимум: %3.1f U</string>
<string name="combo_tdd_average" formatted="false">Средно: %3.1f U</string>
<string name="combo_reservoir_normal">Нормално</string>
<string name="combo_reservoir_low">Ниско</string>
<string name="combo_reservoir_level_insufficient_for_bolus">Няма достатъчно инсулин в резервоара</string>

View file

@ -704,7 +704,6 @@
<string name="bolus_frequency_exceeded">Bolus stejné velikosti už byl během poslední minuty požadován. Jako preventivní ochrana před zdvojeným bolusem byla operace zakázána.</string>
<string name="combo_pump_connected_now">Teď</string>
<string name="combo_activity_reading_pump_history">Načítání historie pumpy</string>
<string name="combo_pump_alerts">Výstrahy</string>
<string name="combo_activity_setting_basal_profile">Nastavení bazálního profilu</string>
<string name="combo_pump_cartridge_low_warrning">V zásobníku je málo inzulínu</string>
<string name="combo_pump_battery_low_warrning">Slabá baterie v pumpě</string>
@ -713,18 +712,12 @@
<string name="combo_error_bolus_verification_failed">Provádění bolusu a čtení historie selhalo. Zkontrolujte pumpu a zadejte bolus přes péči</string>
<string name="combo_error_no_bolus_delivered">Provádění bolusu selhalo. Zdá se, že žádný bolus nebyl podán. Zkontrolujte pumpu a případně pošlete bolus znovu. Jako bezpečnostní opatření podání bolusu není opakováno.</string>
<string name="combo_error_partial_bolus_delivered" formatted="false">Pouze %.2f U z bolusu %.2f bylo podáno díky chybě. Zkontrolujte pumpu a proveďte nápravu.</string>
<string name="combo_history">Historie</string>
<string name="combo_pump_tbr_cancelled_warrning">Varování o ukončeném dočasném bazálu bylo potvrzeno.</string>
<string name="combo_warning">Varování</string>
<string name="combo_reservoir_empty">Prázdný</string>
<string name="combo_reservoir_low">Nízký</string>
<string name="combo_reservoir_normal">Normální</string>
<string name="combo_tdd_average" formatted="false">Průměr: %3.1f U</string>
<string name="combo_tdd_maximum" formatted="false">Maximum: %3.1f U</string>
<string name="combo_tdd_minimum" formatted="false">Minimum: %3.1f U</string>
<string name="combo_no_alert_data_note">Pro přečtení historie chyb dlouze stiskněte tlačítko ALERTS. Varování: může to způsobit chybu, že pumpa bude odmítat všechny připojení a je pak vyžadováno stisknutí tlačítka na pumpě pro obnovení komunikace.</string>
<string name="combo_notification_check_time_date">Je vyžadována aktualizace času na pumpě</string>
<string name="combo_no_tdd_data_note">Pro přečtení celkových denních dávek dlouze stikněte na pumpě tlačítko TDDS. Varování: může to způsobit chybu, že pumpa bude odmítat všechna připojení a je pak vyžadováno stisknutí tlačítka na pumpě pro obnovení komunikace.</string>
<string name="combo_reservoir_level_insufficient_for_bolus">Nedostatek inzulínu pro takovýto bolus</string>
<string name="extendedbolusdeliveryerror">Chyba spuštění extended bolusu</string>
<string name="smb_shortname">SMB</string>
@ -823,8 +816,6 @@
<string name="bolusrecordedonly">Bolus bude pouze zaznamenán</string>
<string name="ns_autobackfill">Automaticky doplňovat chybějící glykémie z NS</string>
<string name="hypo">Hypoglykémie</string>
<string name="combo_tdds">CDD</string>
<string name="combo_read_full_history_info">Dlouhé stisknutí tohoto tlačítka pro plné načtení historie a bazálního profilu z pumpy. Obvykle to není nutné, protože se to děje průběžně, ale může to pomoci v případě změny datumu v pumpě nebo v případě výměny pumpy.</string>
<string name="overview_show_sensitivity">Citlivost</string>
<string name="overview_show_deviations">Odchylky</string>
<string name="overview_show_cob">Zbývající sacharidy</string>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="alert_w31">Warnung W31: Ampulle fast leer</string>
<string name="alert_w32">Warnung W32: Batterie fast leer</string>
<string name="alert_w33">Warnung W33: Zeit/Datum ungültig</string>
<string name="alert_w34">Warnung W34: Garantie abgelaufen</string>
<string name="alert_w36">Warnung W36: TBR abgebrochen</string>
<string name="alert_w38">Warnung W38: Bolus abgebrochen</string>
<string name="alert_w39">Warnung W39: Leihdauer-Warnung</string>
<string name="alert_m20">Wartung M20: Keine Ampulle eingesetzt</string>
<string name="alert_m21">Wartung M21: Ampulle leer</string>
<string name="alert_m22">Wartung M22: Batterie leer</string>
<string name="alert_m23">Wartung M23: Sicherheitsabschaltung</string>
<string name="alert_m24">Wartung M24: Verstopfung</string>
<string name="alert_m25">Wartung M25: Leihdauer abgelaufen</string>
<string name="alert_m26">Wartung M26: Ampullenwechsel nicht abgeschlossen</string>
<string name="alert_m27">Wartung M27: Datenübertragung fehlgeschlagen</string>
<string name="alert_m28">Wartung M28: Zeitüberschreitung bei Pause</string>
<string name="alert_m29">Wartung M29: Batterietyp nicht eingestellt</string>
<string name="alert_m30">Wartung M30: Ampullentyp nicht eingestellt</string>
<string name="alert_e6">Fehler E6: Mechanikfehler</string>
<string name="alert_e7">Fehler E7: Elektronikfehler</string>
<string name="alert_e10">Fehler E10: Fehler beim Zurückfahren</string>
<string name="alert_e13">Fehler E13: Fehler in der Sprachanzeige</string>
</resources>

View file

@ -666,7 +666,6 @@
<string name="combo_pump_state_suspended_by_user">Gestoppt (Benutzer)</string>
<string name="combo_pump_state_suspended_due_to_error">Gestoppt (Fehler)</string>
<string name="combo_pump_state_running">In Betrieb</string>
<string name="combo_tdds">TDDS</string>
<string name="combo_programming_bolus">Bolusabgabe wird vorbereitet</string>
<string name="combo_pump_action_cancelling_tbr">TBR wird abgebrochen</string>
<string name="combo_pump_action_setting_tbr">TBR wird gesetzt (%d%% / %d Min.)</string>
@ -680,7 +679,6 @@
<string name="combo_error_bolus_verification_failed">Der abgegebene Bolus konnte nicht bestätigt werden. Bitte prüfe auf der Pumpe, ob ein Bolus abgegeben wurde und erstelle einen Eintrag im Careportal falls nötig.</string>
<string name="combo_error_no_bolus_delivered">Die Bolusabgabe ist fehlgeschlagen: Es wurde scheinbar kein Bolus abgegeben. Bitte prüfe auf der Pumpe, ob ein Bolus abgegeben wurde. Um doppelte Boli durch Programmfehler zu vermeiden, werden Boli nicht automatisch wiederholt.</string>
<string name="combo_error_partial_bolus_delivered">Wegen eines Fehlers wurden nur %.2f IE von den angeforderten %.2f IE abgegeben. Bitte prüfe den abgegebenen Bolus auf der Pumpe.</string>
<string name="combo_history">Historie</string>
<string name="combo_pump_action_refreshing">Status wird aktualisiert</string>
<string name="combo_pump_state_initializing">Die Pumpe wird initialisiert</string>
<string name="combo_pump_connected_now">Jetzt</string>
@ -689,19 +687,13 @@
<string name="combo_reservoir_empty">Leer</string>
<string name="combo_reservoir_low">Niedrig</string>
<string name="combo_reservoir_normal">Normal</string>
<string name="combo_tdd_average">Durchschnitt: %3.1f IE</string>
<string name="combo_tdd_maximum">Maximum: %3.1f IE</string>
<string name="combo_tdd_minimum">Minimum: %3.1f IE</string>
<string name="combo_pump_unsupported_operation">Diese Aktion wird von der Pumpe nicht unterstützt</string>
<string name="combo_pump_alerts">Alarme</string>
<string name="combo_pump_battery_low_warrning">Die Batterie in der Pumpe ist fast leer</string>
<string name="combo_pump_cartridge_low_warrning">Das Reservoir in der Pumpe ist fast leer</string>
<string name="combo_is_in_error_state">Die Pumpe zeigt einen Fehler an E%d: %s</string>
<string name="combo_force_disabled_notification">Unsichere Verwendung: In der Pumpe ist nicht das erste Basalratenprofil gewählt. Der Loop wird deaktiviert bis dies korrigiert ist.</string>
<string name="combo_low_suspend_forced_notification">Unsichere Verwendung: Ein erweiterter oder Multiwave-Bolus ist aktiv. Der Loop wird für die nächsten 6 Stunden kein zusätzliches Insulin abgeben.</string>
<string name="combo_no_alert_data_note">Um die Fehlerhistorie der Pumpe zu lesen, drücke lange auf ALARME.</string>
<string name="combo_notification_check_time_date">Bitte aktualisiere die Uhrzeit der Pumpe</string>
<string name="combo_no_tdd_data_note">Um die TDD-Statistik der Pumpe zu lesen, drücken Sie den TDDS Knopf lange.\nWARNUNG: Es gibt einen bekannten Fehler in der Pumpe der dazu führt, dass die Pumpe nach dieser Aktion erst wieder Verbindungen annimmt, wenn auf der Pumpe selbst ein Konpf gedrückt wird. Aus diesem Grund sollte diese Aktion nicht durchgeführt werden.</string>
<string name="combo_reservoir_level_insufficient_for_bolus">Nicht mehr genug Insulin im Reservoir für den Bolus</string>
<string name="yes">Ja</string>
<string name="no">Nein</string>
@ -723,7 +715,6 @@
<string name="openapsama_link_to_preferncejson_doc_txt">Achtung! Normalerweise musst Du diese Werte nicht ändern. Bitte KLICKE HIER und LESE den Text. Verändere Werte erst, wenn Du den Inhalt des Textes verstanden hast.</string>
<string name="combo_actvity_reading_basal_profile">Basalratenprofil wird gelesen</string>
<string name="pump_basebasalrate">%.2f IE/h</string>
<string name="combo_read_full_history_info">Drücke den Button lange, um die gesamte Historie und das Basal-Profil der Pumpe auszulesen. Dies ist eigentlich unnötig, weil die Historie regelmäßig gelesen wird. Hilfreich kann dies jedoch sein, wenn Datum und Zeit grundlegend verändert wurden oder die Pumpe ausgetauscht wurde.</string>
<string name="combo_error_no_connection_no_bolus_delivered">Keine Verbindung zur Pumpe: Es wurde kein Bolus abgegeben.</string>
<string name="extendedbolusdeliveryerror">Fehler bei der Abgabe eines verlängerten Bolus</string>
<string name="combo_bolus_rejected_due_to_pump_history_change">Nach der Berechnung des Bolus hat sich die Pumpenhistorie geändert. Daher wurde kein Bolus abgegeben. Bitte prüfe, ob überhaupt noch ein Bolus benötigt wird. Wenn die gleiche Bolusmenge erforderlich ist, warte zwei Minuten ab, denn es werden aus Sicherheitsgründen keine gleich großen Boli abgegeben, wenn sie innerhalb von zwei Minuten angefordert wurden (unabhängig davon, ob sie verabreicht wurden oder nicht).</string>

View file

@ -676,7 +676,6 @@
<string name="zerovalueinprofile" formatted="false">Perfil invalido: %s</string>
<string name="combo_programming_bolus">Programando bomba para emitir bolo</string>
<string name="combo_refresh">Actualizar</string>
<string name="combo_tdds">TDDS</string>
<string name="combo_pump_state_label">Estado</string>
<string name="combo_pump_activity_label">Actividad</string>
<string name="combo_no_pump_connection" formatted="false">Ninguna coneccnion por %d min</string>
@ -694,21 +693,14 @@
<string name="bolus_frequency_exceeded">Un bolo de mismo valor ha sido dado durante el pasado minuto. Para evitar bolos dobles y asegurarse contra bugs esto no es permitido.</string>
<string name="combo_pump_connected_now">Ahora</string>
<string name="combo_activity_reading_pump_history">Leiendo historia bomba</string>
<string name="combo_pump_alerts">Alarmas</string>
<string name="combo_activity_setting_basal_profile">" Activando perfil base "</string>
<string name="combo_pump_cartridge_low_warrning">"Nivel del deposito bajo "</string>
<string name="combo_pump_battery_low_warrning">Bateria casi agotada</string>
<string name="combo_is_in_error_state" formatted="false">La bomba muesta el error E%d: %s</string>
<string name="combo_no_alert_data_note">Para leer historial de los errores, pincha unos segundo el boton \"ALARMAS\" ATENCION: esto puede causar un bug. La bomba no vuelve a conectarse - necesitas pulsar un boton en la misma bomba para reiniciarse. Deberias evitar esto.</string>
<string name="combo_no_tdd_data_note">Para leer el hisorial TDD de la bomba pulsa el boton TDDS unso segundos. ATENCION: esto puede causar un bug. La bomba no vuelve a conectarse - necesitas pulsar un boton en la misma bomba para reiniciarse. Deberias evitar esto.</string>
<string name="combo_tdd_minimum" formatted="false">Mínimo: %3.1f U</string>
<string name="combo_tdd_average" formatted="false">Media: %3.1f U</string>
<string name="combo_tdd_maximum" formatted="false">Máximo: %3.1f U</string>
<string name="combo_reservoir_low">Bajo</string>
<string name="combo_reservoir_empty">Vacio</string>
<string name="combo_reservoir_normal">Normal</string>
<string name="combo_notification_check_time_date">Se necesita actualizar reloj de la bomba</string>
<string name="combo_history">Historial</string>
<string name="combo_warning">Alerta</string>
<string name="combo_pump_tbr_cancelled_warrning">TBR cancelada, advertencia acceptada</string>
<string name="combo_error_no_bolus_delivered">Emision del bolo fallado. Ningún bolo se ha emitido. Para asegurarse, por favor controle la bomba para evitar bolo doble. Para evitar bugs no se reinician bolos automaticamente.</string>

View file

@ -684,7 +684,6 @@
<string name="zerovalueinprofile">Profile incorrect: %s</string>
<string name="combo_programming_bolus">Programmer la pompe pour administrer un bolus</string>
<string name="combo_refresh">Actualiser</string>
<string name="combo_tdds">TDDS</string>
<string name="combo_pump_state_label">État</string>
<string name="combo_pump_activity_label">Activité</string>
<string name="combo_no_pump_connection" formatted="false">Pas de connexion depuis %d min</string>
@ -708,21 +707,14 @@
<string name="bolus_frequency_exceeded">Un bolus avec la même quantité dinsuline a été demandé au cours de la dernière minute. Pour prévenir ladministration accidentelle de deux bolus à la fois et pour protéger contre les bugs quand ceci (bolus) non autorisé</string>
<string name="combo_pump_connected_now">Maintenant</string>
<string name="combo_activity_reading_pump_history">Lecture historique pompe</string>
<string name="combo_pump_alerts">Alertes</string>
<string name="combo_activity_setting_basal_profile">Définir le profil basal</string>
<string name="combo_pump_cartridge_low_warrning">Niveau cartouche pompe bas</string>
<string name="combo_pump_battery_low_warrning">Niveau batterie pompe bas</string>
<string name="combo_is_in_error_state" formatted="false">La pompe affiche lerreur E%d: %s</string>
<string name="combo_no_alert_data_note">Pour lire lhistorique des erreurs de pompe, Appuyez longuement sur le bouton ALERTES, WARNING : ceci peut provoquer un bug et ce dernier va ordonner la pompe à rejeter toutes les tentatives de connexion et qui va nécessiter dappuyer un bouton sur la pompe pour restaurer et par conséquent le bug devrait être évité</string>
<string name="combo_no_tdd_data_note">Pour lire lhistorique DTQ de la pompe, Appuyez longuement les boutons DTQS, WARNING : ceci peut provoquer un bug ce qui ordonne la pompe à rejeter toutes les tentatives de connexion et qui va nécessiter dappuyer un bouton sur la pompe pour restaurer et par conséquent le bug devrait être évité</string>
<string name="combo_tdd_minimum" formatted="false">Minimum: %3.1f U</string>
<string name="combo_tdd_average" formatted="false">Moyen: %3.1f U</string>
<string name="combo_tdd_maximum" formatted="false">Maximum: %3.1f U</string>
<string name="combo_reservoir_low">Bas</string>
<string name="combo_reservoir_empty">Vide</string>
<string name="combo_reservoir_normal">Normal</string>
<string name="combo_notification_check_time_date">Mise à jour nécessaire pour l\'heure de la pompe</string>
<string name="combo_history">Historique</string>
<string name="combo_warning">Warning</string>
<string name="combo_pump_tbr_cancelled_warrning">TBR ANNULÉ warning confirmé</string>
<string name="combo_error_no_bolus_delivered">Administration bolus échouée. Il semble quaucun bolus na été administré. Pour être sûr, Veuillez vérifier la pompe pour éviter un double bolus ensuite re bolusez une nouvelle fois</string>

View file

@ -693,11 +693,8 @@
<string name="combo_notification_check_time_date">Pomp klok moet bijgesteld worden</string>
<string name="combo_reservoir_empty">Leeg</string>
<string name="combo_reservoir_low">Bijna leeg</string>
<string name="combo_tdd_maximum">Maximum: %3.1f E</string>
<string name="combo_reservoir_normal">Normaal</string>
<string name="combo_pump_action_refreshing">Vernieuwen</string>
<string name="combo_history">Historiek</string>
<string name="combo_pump_alerts">Storingen</string>
<string name="combo_pump_battery_low_warrning">Batterij pomp is bijna leeg</string>
<string name="combo_pump_unsupported_operation">Gevraagde is niet momeglijk met de pomp</string>
<string name="combo_pump_connected_now">Zojuist</string>
@ -709,19 +706,14 @@
<string name="combo_pump_cartridge_low_warrning">Insuline ampul is bijna leeg</string>
<string name="combo_is_in_error_state">Pomp is in storing, controleer op de pomp: E%d %s</string>
<string name="combo_pump_action_bolusing">Bolus (%.1f E)</string>
<string name="combo_tdd_minimum">Minimum: %3.1f E</string>
<string name="combo_tdd_average">Gemiddelde: %3.1f E</string>
<string name="combo_activity_setting_basal_profile">Instellen van basaal profiel</string>
<string name="combo_activity_reading_pump_history">Lezen van pomp historiek</string>
<string name="combo_no_alert_data_note">Om de pomp fouthistoriek op te halen, druk lang op de Storingen knop.</string>
<string name="combo_error_partial_bolus_delivered">Maar %.2f E van de gevraagde %.2f E zijn toegediend door een storing. Gelieve op de pomp te controleren en het gepaste gevolg uit te voeren.</string>
<string name="combo_no_tdd_data_note">"Om de TTD van de pomp op te halen, lang duwen op de TDDS knop OPGELET: dit kan een bug veroorzaken waardoor de pomp alle verbindingen verbreekt en het vereist is op een knop op de pomp te duwen, dit wordt daarom afgeraden."</string>
<string name="combo_error_bolus_verification_failed">Toedienen en controleren van de bolus in de pomp historiek is mislukt, controleer de pomp en creëer een manuele bolus in het Careportal tabblad</string>
<string name="combo_error_no_bolus_delivered">Bolus toedienen mislukt. Waarschijnlijk is er geen bolus toegediend. Gelieve de pomp te controleren om een dubbele bolus te vermijden. Als bescherming tegen programmeerfouten worden bolussen niet automatisch opnieuw uitgevoerd.</string>
<string name="combo_pump_activity_label">Actie</string>
<string name="combo_pump_action_setting_tbr">Instellen TBR (%d%% / %d min)</string>
<string name="combo_force_disabled_notification">Onvoorzichtig gebruik: Vertraagde of multi wave bolussen zijn toegediend in de afgelopen 6 uur op het geselecteerde basaal patroon is niet 1. Loop is onderbroken tot de 6 uur nadat deze bolussen of andere basale patronen zijn gedetecteerd. Alleen normale bolussen en basaal patroon 1 zijn mogelijk binnen basaal patroon 1</string>
<string name="combo_tdds">TDDS</string>
<string name="combo_low_suspend_forced_notification">Opgelet: verlengde en multi wafe bolussen zijn actief. Loop is naar onderdruk lage waardes enkel overgeschakeld gedurende 6 uur. Alleen gewone bolussen worden onderdsteund in loop modus.</string>
<string name="combo_reservoir_level_insufficient_for_bolus">Niet genoeg insuline aanwezig in reservoir voor de bolus</string>
<string name="careportal_combobolus">Combinatie-Bolus</string>
@ -732,7 +724,6 @@
<string name="combo_actvity_reading_basal_profile">Basaal profiel wordt gelezen</string>
<string name="basalprofilenotaligned">Basale patroon niet geschikt op complete uren: %s</string>
<string name="zerovalueinprofile">Ongeldig profiel: %s</string>
<string name="combo_read_full_history_info">Lang duwen op deze knop zal de volledige historiek en basaal profiel uit de pomp ophalen. Dit is normaal gezien niet nodig, daar de pomp historiek permanent wordt gelezen, maar kan nuttig zijn wanneer de pomp dat en tijd grote afwijkingen hadden of de pomp vervangen is.</string>
<string name="combo_error_no_connection_no_bolus_delivered">Er kon geen verbinding met de pomp gemaakt worden. De Bolus is niet toegediend.</string>
<string name="extendedbolusdeliveryerror">Vertraagde bolus toedien storing</string>
<string name="combo_bolus_rejected_due_to_pump_history_change">De pomp historiek is gewijzigd nadat de bolus berend was. De bolus is NIET toegediend. Programmeer een nieuwe bolus indien nodig. Als dezelfde bolus hoeveelheid moet worden toegediend, gelieve 2 minuten te wachten. Gelijke bolussen worden geweigerd om veiligheidsredenen (toegediend of niet).</string>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="alert_w31">Warning W31: Cartridge low</string>
<string name="alert_w32">Warning W32: Battery low</string>
<string name="alert_w33">Warning W33: Invalid time/date</string>
<string name="alert_w34">Warning W34: End of warranty</string>
<string name="alert_w36">Warning W36: TBR cancelled</string>
<string name="alert_w38">Warning W38: Bolus canelled</string>
<string name="alert_w39">Warning W39: Loantime warning</string>
<string name="alert_m20">Maintenance M20: Cartridge not inserted</string>
<string name="alert_m21">Maintenance M21: Cartridge empty</string>
<string name="alert_m22">Maintenance M22: Battery empty</string>
<string name="alert_m23">Maintenance M23: Automatic off</string>
<string name="alert_m24">Maintenance M24: Occlusion</string>
<string name="alert_m25">Maintenance M25: Loantime over - end of operation</string>
<string name="alert_m26">Maintenance M26: Cartridge change not completed</string>
<string name="alert_m27">Maintenance M27: Data download failed</string>
<string name="alert_m28">Maintenance M28: Pause mode timeout</string>
<string name="alert_m29">Maintenance M29: Battery type not set</string>
<string name="alert_m30">Maintenance M30: Cartridge type not set</string>
<string name="alert_e6">Error E6: Mechanical error</string>
<string name="alert_e7">Error E7: Electronic error</string>
<string name="alert_e10">Error E10: Rewind error</string>
<string name="alert_e13">Error E13: Language error</string>
</resources>

View file

@ -203,7 +203,7 @@
<string name="openapsma_maxbasal_title">Max U/hr a Temp Basal can be set to</string>
<string name="openapsma_maxbasal_summary">This value is called max basal in OpenAPS context</string>
<string name="openapsma_maxiob_title">Maximum basal IOB OpenAPS can deliver [U]</string>
<string name="openapsma_maxiob_summary">This value is called Max IOB in OpenAPS context\nThis will default to zero. After several days or weeks, depending on your comfort level, you may choose to adjust this number.</string>
<string name="openapsma_maxiob_summary">This value is called Max IOB in OpenAPS context\nThis is maximal insulin in [U] APS can deliver at once.</string>
<string name="bg_lang">Bulgarian</string>
<string name="dismiss">DISMISS</string>
<string name="language">Language</string>
@ -780,7 +780,6 @@
<string name="zerovalueinprofile" formatted="false">Invalid profile: %s</string>
<string name="combo_programming_bolus">Programming pump for bolusing</string>
<string name="combo_refresh">Refresh</string>
<string name="combo_tdds">TDDS</string>
<string name="combo_pump_state_label">State</string>
<string name="combo_pump_activity_label">Activity</string>
<string name="combo_no_pump_connection">No connection for %d min</string>
@ -801,23 +800,15 @@
<string name="combo_pump_connected_now">Now</string>
<string name="combo_activity_reading_pump_history">Reading pump history</string>
<string name="danar_history">pump history</string>
<string name="combo_pump_alerts">Alerts</string>
<string name="combo_activity_setting_basal_profile">Setting basal profile</string>
<string name="combo_pump_cartridge_low_warrning">Pump cartridge level is low</string>
<string name="combo_pump_battery_low_warrning">Pump battery is low</string>
<string name="combo_is_in_error_state">The pump is showing the error E%d: %s</string>
<string name="combo_no_alert_data_note">To read the pump\'s error history, long press this button</string>
<string name="combo_no_tdd_data_note">To read the pump\'s TDD history, long press this button</string>
<string name="combo_tdd_minimum">Minimum: %3.1f U</string>
<string name="combo_tdd_average">Average: %3.1f U</string>
<string name="combo_tdd_maximum">Maximum: %3.1f U</string>
<string name="combo_reservoir_low">Low</string>
<string name="combo_reservoir_empty">Empty</string>
<string name="combo_reservoir_normal">Normal</string>
<string name="combo_notification_check_time_date">Pump clock update needed</string>
<string name="combo_history">History</string>
<string name="combo_warning">Warning</string>
<string name="combo_read_full_history_info">Long press this button to force a full read of history and basal profile from the pump. This is generally not needed, since the pump\'s history is read continuously, but can be useful if the pump\'s date and time changed significantly or the pump was replaced.</string>
<string name="combo_pump_tbr_cancelled_warrning">TBR CANCELLED warning was confirmed</string>
<string name="combo_error_no_connection_no_bolus_delivered">The pump could not be reached. No bolus was given</string>
<string name="combo_error_no_bolus_delivered">Bolus delivery failed. It appears no bolus was delivered. To be sure, please check the pump to avoid a double bolus and then bolus again. To guard against bugs, boluses are not automatically retried.</string>
@ -996,5 +987,12 @@
<string name="smbnotallowedinopenloopmode">SMB not allowed in open loop mode</string>
<string name="food_short">Food</string>
<string name="iobcobcalculator" translatable="false">IobCobCalculator</string>
<string name="reset">reset</string>
<string name="waitingfortimesynchronization">Waiting for time synchronization (%d sec)</string>
<string name="loopdisconnectedfor">Disconnected (%d m)</string>
<string name="automatic_careportal_events">Automatic careportal events</string>
<string name="automatically_upload_insulin_cannula_and_battery_changes_to_nightscout">Automatically upload insulin, cannula and battery changes and pump alarms to Nightscout</string>
<string name="key_openapssmb_max_iob" translatable="false">openapsmb_max_iob</string>
<string name="openapssmb_maxiob_title">Maximum total IOB OpenAPS can\'t go over [U]</string>
<string name="openapssmb_maxiob_summary">This value is called Max IOB in OpenAPS context\nOpenAPS will not add more insulin if current IOB is greater than this value</string>
</resources>

View file

@ -19,4 +19,9 @@
android:key="insight_real_tbr_cancel"
android:title="@string/insight_use_real_tbr_cancels"
android:summary="@string/insight_actually_cancel_tbr_summary"/>
</PreferenceScreen >
<SwitchPreference
android:defaultValue="false"
android:key="insight_automatic_careportal_events"
android:title="@string/automatic_careportal_events"
android:summary="@string/automatically_upload_insulin_cannula_and_battery_changes_to_nightscout"/>
</PreferenceScreen>

View file

@ -11,11 +11,11 @@
android:dialogMessage="@string/openapsma_maxbasal_summary"
android:title="@string/openapsma_maxbasal_title" />
<EditTextPreference
android:defaultValue="1.5"
android:key="@string/key_openapsma_max_iob"
android:defaultValue="3"
android:key="@string/key_openapssmb_max_iob"
android:numeric="decimal"
android:dialogMessage="@string/openapsma_maxiob_summary"
android:title="@string/openapsma_maxiob_title" />
android:dialogMessage="@string/openapssmb_maxiob_summary"
android:title="@string/openapssmb_maxiob_title" />
<SwitchPreference
android:defaultValue="false"
android:key="openapsama_useautosens"

View file

@ -17,6 +17,7 @@ import info.nightscout.androidaps.data.ConstraintChecker;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.queue.CommandQueue;
import info.nightscout.utils.SP;
import static org.mockito.ArgumentMatchers.anyBoolean;
@ -122,11 +123,17 @@ public class AAPSMocker {
when(MainApp.getDbHelper()).thenReturn(databaseHelper);
}
public static void mockCommandQueue() {
CommandQueue queue = mock(CommandQueue.class);
when(ConfigBuilderPlugin.getCommandQueue()).thenReturn(queue);
}
public static Profile getValidProfile() {
try {
if (profile == null)
profile = new Profile(new JSONObject(validProfile), Constants.MGDL);
} catch (JSONException ignored) {}
} catch (JSONException ignored) {
}
return profile;
}

View file

@ -0,0 +1,45 @@
package info;
import org.junit.Assert;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import java.util.HashMap;
import info.nightscout.utils.SP;
import static org.powermock.api.mockito.PowerMockito.when;
public class SPMocker {
static HashMap<String, Object> data = new HashMap<>();
public static void prepareMock() {
PowerMockito.mockStatic(SP.class);
try {
PowerMockito.when(SP.class, "putString", ArgumentMatchers.anyString(), ArgumentMatchers.anyString()).then(invocation -> {
String key = invocation.getArgument(0);
String value = invocation.getArgument(1);
data.put(key,value);
return null;
});
PowerMockito.when(SP.class, "getString", ArgumentMatchers.anyString(), ArgumentMatchers.anyString()).then(invocation -> {
String key = invocation.getArgument(0);
String def = invocation.getArgument(1);
String value = (String) data.get(key);
if (value == null) value = def;
return value;
});
} catch (Exception e) {
Assert.fail("Unable to mock the construction of "
+ "the SP object");
}
}
}

View file

@ -0,0 +1,83 @@
package info.nightscout.androidaps.data;
import junit.framework.Assert;
import org.json.JSONArray;
import org.json.JSONException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import info.AAPSMocker;
import info.SPMocker;
import info.nightscout.androidaps.MainApp;
import info.nightscout.utils.SP;
@RunWith(PowerMockRunner.class)
@PrepareForTest({SP.class, MainApp.class})
public class QuickWizardTest {
String data1 = "{\"buttonText\":\"Meal\",\"carbs\":36,\"validFrom\":0,\"validTo\":18000," +
"\"useBG\":0,\"useCOB\":0,\"useBolusIOB\":0,\"useBasalIOB\":0,\"useTrend\":0,\"useSuperBolus\":0,\"useTemptarget\":0}";
String data2 = "{\"buttonText\":\"Lunch\",\"carbs\":18,\"validFrom\":36000,\"validTo\":39600," +
"\"useBG\":0,\"useCOB\":0,\"useBolusIOB\":1,\"useBasalIOB\":2,\"useTrend\":0,\"useSuperBolus\":0,\"useTemptarget\":0}";
JSONArray array;
QuickWizard qv = new QuickWizard();
public QuickWizardTest() {
try {
array = new JSONArray("[" + data1 + "," + data2 + "]");
} catch (JSONException e) {
e.printStackTrace();
}
}
@Before
public void mock() {
AAPSMocker.mockMainApp();
SPMocker.prepareMock();
}
@Test
public void setDataTest() {
qv.setData(array);
Assert.assertEquals(2, qv.size());
}
@Test
public void saveTest() {
qv.setData(array);
qv.save();
Assert.assertEquals("[{\"useBolusIOB\":0,\"buttonText\":\"Meal\",\"useTrend\":0,\"carbs\":36,\"useCOB\":0,\"useBasalIOB\":0,\"useTemptarget\":0,\"useBG\":0,\"validFrom\":0,\"useSuperBolus\":0,\"validTo\":18000},{\"useBolusIOB\":1,\"buttonText\":\"Lunch\",\"useTrend\":0,\"carbs\":18,\"useCOB\":0,\"useBasalIOB\":2,\"useTemptarget\":0,\"useBG\":0,\"validFrom\":36000,\"useSuperBolus\":0,\"validTo\":39600}]", SP.getString("QuickWizard", "d"));
}
@Test
public void getTest() {
qv.setData(array);
Assert.assertEquals("Lunch", qv.get(1).buttonText());
}
@Test
public void isActive() {
}
@Test
public void getActive() {
}
@Test
public void newEmptyItemTest() {
Assert.assertNotNull(qv.newEmptyItem());
}
@Test
public void addOrUpdate() {
}
@Test
public void remove() {
}
}

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