Merge branch 'dev' of https://github.com/MilosKozak/AndroidAPS into dev
This commit is contained in:
commit
50a3b45f20
|
@ -10,6 +10,8 @@ buildscript {
|
|||
}
|
||||
}
|
||||
apply plugin: "com.android.application"
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply plugin: "io.fabric"
|
||||
apply plugin: "jacoco-android"
|
||||
|
@ -27,6 +29,7 @@ ext {
|
|||
repositories {
|
||||
maven { url 'https://maven.fabric.io/public' }
|
||||
jcenter { url "https://jcenter.bintray.com/" }
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
def generateGitBuild = { ->
|
||||
|
@ -92,6 +95,9 @@ android {
|
|||
moduleName "BleCommandUtil"
|
||||
}
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
lintOptions {
|
||||
// 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
|
||||
|
@ -249,6 +255,7 @@ dependencies {
|
|||
androidTestImplementation "org.mockito:mockito-core:2.8.47"
|
||||
androidTestImplementation "com.google.dexmaker:dexmaker:${dexmakerVersion}"
|
||||
androidTestImplementation "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
}
|
||||
|
||||
task unzip(type: Copy) {
|
||||
|
|
|
@ -48,9 +48,12 @@ import info.nightscout.androidaps.events.EventFeatureRunning;
|
|||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.events.EventRefreshGui;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
|
||||
import info.nightscout.androidaps.plugins.general.versionChecker.VersionCheckerUtilsKt;
|
||||
import info.nightscout.androidaps.setupwizard.SetupWizardActivity;
|
||||
import info.nightscout.androidaps.tabs.TabPageAdapter;
|
||||
import info.nightscout.androidaps.utils.AndroidPermission;
|
||||
|
@ -59,7 +62,6 @@ import info.nightscout.androidaps.utils.LocaleHelper;
|
|||
import info.nightscout.androidaps.utils.OKDialog;
|
||||
import info.nightscout.androidaps.utils.PasswordProtection;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
import info.nightscout.androidaps.utils.VersionChecker;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||
|
@ -115,7 +117,11 @@ public class MainActivity extends AppCompatActivity {
|
|||
public void onPageScrollStateChanged(int state) {
|
||||
}
|
||||
});
|
||||
VersionChecker.check();
|
||||
|
||||
//Check here if loop plugin is disabled. Else check via constraints
|
||||
if (!LoopPlugin.getPlugin().isEnabled(PluginType.LOOP))
|
||||
VersionCheckerUtilsKt.checkVersion();
|
||||
|
||||
FabricPrivacy.setUserStats();
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.receivers.DBAccessRec
|
|||
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.versionChecker.VersionCheckerPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin;
|
||||
import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin;
|
||||
|
@ -119,7 +120,7 @@ public class MainApp extends Application {
|
|||
log.debug("onCreate");
|
||||
sInstance = this;
|
||||
sResources = getResources();
|
||||
sConstraintsChecker = new ConstraintChecker(this);
|
||||
sConstraintsChecker = new ConstraintChecker();
|
||||
sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
|
||||
|
||||
try {
|
||||
|
@ -179,6 +180,7 @@ public class MainApp extends Application {
|
|||
if (Config.OTHERPROFILES) pluginsList.add(LocalProfilePlugin.getPlugin());
|
||||
pluginsList.add(TreatmentsPlugin.getPlugin());
|
||||
if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin());
|
||||
if (Config.SAFETY) pluginsList.add(VersionCheckerPlugin.INSTANCE);
|
||||
if (Config.SAFETY) pluginsList.add(StorageConstraintPlugin.getPlugin());
|
||||
if (Config.APS) pluginsList.add(ObjectivesPlugin.getPlugin());
|
||||
pluginsList.add(SourceXdripPlugin.getPlugin());
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
package info.nightscout.androidaps.data;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
|
@ -15,13 +19,6 @@ import info.nightscout.androidaps.interfaces.PluginType;
|
|||
|
||||
public class ConstraintChecker implements ConstraintsInterface {
|
||||
|
||||
private MainApp mainApp;
|
||||
|
||||
public ConstraintChecker(MainApp mainApp) {
|
||||
this.mainApp = mainApp;
|
||||
}
|
||||
|
||||
|
||||
public Constraint<Boolean> isLoopInvokationAllowed() {
|
||||
return isLoopInvocationAllowed(new Constraint<>(true));
|
||||
}
|
||||
|
@ -79,9 +76,9 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||
public Constraint<Boolean> isLoopInvocationAllowed(@NonNull Constraint<Boolean> value) {
|
||||
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -91,9 +88,9 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Boolean> isClosedLoopAllowed(Constraint<Boolean> value) {
|
||||
public Constraint<Boolean> isClosedLoopAllowed(@NonNull Constraint<Boolean> value) {
|
||||
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -103,9 +100,9 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Boolean> isAutosensModeEnabled(Constraint<Boolean> value) {
|
||||
public Constraint<Boolean> isAutosensModeEnabled(@NonNull Constraint<Boolean> value) {
|
||||
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -115,9 +112,9 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Boolean> isAMAModeEnabled(Constraint<Boolean> value) {
|
||||
public Constraint<Boolean> isAMAModeEnabled(@NonNull Constraint<Boolean> value) {
|
||||
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -127,9 +124,9 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Boolean> isSMBModeEnabled(Constraint<Boolean> value) {
|
||||
public Constraint<Boolean> isSMBModeEnabled(@NonNull Constraint<Boolean> value) {
|
||||
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -139,9 +136,9 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Boolean> isUAMEnabled(Constraint<Boolean> value) {
|
||||
public Constraint<Boolean> isUAMEnabled(@NonNull Constraint<Boolean> value) {
|
||||
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -151,8 +148,8 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
public Constraint<Boolean> isAdvancedFilteringEnabled(@NonNull Constraint<Boolean> value) {
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -162,8 +159,8 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Boolean> isSuperBolusEnabled(Constraint<Boolean> value) {
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
public Constraint<Boolean> isSuperBolusEnabled(@NonNull Constraint<Boolean> value) {
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -173,8 +170,8 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) {
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
public Constraint<Double> applyBasalConstraints(@NonNull Constraint<Double> absoluteRate, Profile profile) {
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -184,8 +181,8 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
public Constraint<Integer> applyBasalPercentConstraints(@NonNull Constraint<Integer> percentRate, Profile profile) {
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -195,8 +192,8 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
public Constraint<Double> applyBolusConstraints(@NonNull Constraint<Double> insulin) {
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -206,8 +203,8 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Double> applyExtendedBolusConstraints(Constraint<Double> insulin) {
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
public Constraint<Double> applyExtendedBolusConstraints(@NonNull Constraint<Double> insulin) {
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -217,8 +214,8 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
public Constraint<Integer> applyCarbsConstraints(@NonNull Constraint<Integer> carbs) {
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
@ -228,8 +225,8 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Double> applyMaxIOBConstraints(Constraint<Double> maxIob) {
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
public Constraint<Double> applyMaxIOBConstraints(@NonNull Constraint<Double> maxIob) {
|
||||
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
|
|
|
@ -1,178 +0,0 @@
|
|||
package info.nightscout.androidaps.data;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||
import info.nightscout.androidaps.utils.Round;
|
||||
|
||||
/**
|
||||
* Created by mike on 04.01.2017.
|
||||
*/
|
||||
|
||||
public class GlucoseStatus {
|
||||
private static Logger log = LoggerFactory.getLogger(GlucoseStatus.class);
|
||||
public double glucose = 0d;
|
||||
public double delta = 0d;
|
||||
public double avgdelta = 0d;
|
||||
public double short_avgdelta = 0d;
|
||||
public double long_avgdelta = 0d;
|
||||
public long date = 0L;
|
||||
|
||||
|
||||
public String log() {
|
||||
return "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " +
|
||||
"Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" +
|
||||
"Short avg. delta: " + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl " +
|
||||
"Long avg. delta: " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl";
|
||||
}
|
||||
|
||||
public GlucoseStatus() {
|
||||
}
|
||||
|
||||
public GlucoseStatus round() {
|
||||
this.glucose = Round.roundTo(this.glucose, 0.1);
|
||||
this.delta = Round.roundTo(this.delta, 0.01);
|
||||
this.avgdelta = Round.roundTo(this.avgdelta, 0.01);
|
||||
this.short_avgdelta = Round.roundTo(this.short_avgdelta, 0.01);
|
||||
this.long_avgdelta = Round.roundTo(this.long_avgdelta, 0.01);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static GlucoseStatus getGlucoseStatusData() {
|
||||
return getGlucoseStatusData(false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) {
|
||||
// load 45min
|
||||
//long fromtime = DateUtil.now() - 60 * 1000L * 45;
|
||||
//List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false);
|
||||
|
||||
List<BgReading> data = IobCobCalculatorPlugin.getPlugin().getBgReadings();
|
||||
|
||||
if (data == null) {
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug("data=null");
|
||||
return null;
|
||||
}
|
||||
|
||||
int sizeRecords = data.size();
|
||||
if (sizeRecords == 0) {
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug("sizeRecords==0");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (data.get(0).date < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug("olddata");
|
||||
return null;
|
||||
}
|
||||
|
||||
BgReading now = data.get(0);
|
||||
long now_date = now.date;
|
||||
double change;
|
||||
|
||||
if (sizeRecords == 1) {
|
||||
GlucoseStatus status = new GlucoseStatus();
|
||||
status.glucose = now.value;
|
||||
status.short_avgdelta = 0d;
|
||||
status.delta = 0d;
|
||||
status.long_avgdelta = 0d;
|
||||
status.avgdelta = 0d; // for OpenAPS MA
|
||||
status.date = now_date;
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug("sizeRecords==1");
|
||||
return status.round();
|
||||
}
|
||||
|
||||
ArrayList<Double> now_value_list = new ArrayList<>();
|
||||
ArrayList<Double> last_deltas = new ArrayList<>();
|
||||
ArrayList<Double> short_deltas = new ArrayList<>();
|
||||
ArrayList<Double> long_deltas = new ArrayList<>();
|
||||
|
||||
// Use the latest sgv value in the now calculations
|
||||
now_value_list.add(now.value);
|
||||
|
||||
for (int i = 1; i < sizeRecords; i++) {
|
||||
if (data.get(i).value > 38) {
|
||||
BgReading then = data.get(i);
|
||||
long then_date = then.date;
|
||||
double avgdelta;
|
||||
long minutesago;
|
||||
|
||||
minutesago = Math.round((now_date - then_date) / (1000d * 60));
|
||||
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
|
||||
change = now.value - then.value;
|
||||
avgdelta = change / minutesago * 5;
|
||||
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug(then.toString() + " minutesago=" + minutesago + " avgdelta=" + avgdelta);
|
||||
|
||||
// use the average of all data points in the last 2.5m for all further "now" calculations
|
||||
if (0 < minutesago && minutesago < 2.5) {
|
||||
// Keep and average all values within the last 2.5 minutes
|
||||
now_value_list.add(then.value);
|
||||
now.value = average(now_value_list);
|
||||
// short_deltas are calculated from everything ~5-15 minutes ago
|
||||
} else if (2.5 < minutesago && minutesago < 17.5) {
|
||||
//console.error(minutesago, avgdelta);
|
||||
short_deltas.add(avgdelta);
|
||||
// last_deltas are calculated from everything ~5 minutes ago
|
||||
if (2.5 < minutesago && minutesago < 7.5) {
|
||||
last_deltas.add(avgdelta);
|
||||
}
|
||||
// long_deltas are calculated from everything ~20-40 minutes ago
|
||||
} else if (17.5 < minutesago && minutesago < 42.5) {
|
||||
long_deltas.add(avgdelta);
|
||||
} else {
|
||||
// Do not process any more records after >= 42.5 minutes
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GlucoseStatus status = new GlucoseStatus();
|
||||
status.glucose = now.value;
|
||||
status.date = now_date;
|
||||
|
||||
status.short_avgdelta = average(short_deltas);
|
||||
|
||||
if (last_deltas.isEmpty()) {
|
||||
status.delta = status.short_avgdelta;
|
||||
} else {
|
||||
status.delta = average(last_deltas);
|
||||
}
|
||||
|
||||
status.long_avgdelta = average(long_deltas);
|
||||
status.avgdelta = status.short_avgdelta; // for OpenAPS MA
|
||||
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug(status.log());
|
||||
return status.round();
|
||||
}
|
||||
|
||||
public static double average(ArrayList<Double> array) {
|
||||
double sum = 0d;
|
||||
|
||||
if (array.size() == 0)
|
||||
return 0d;
|
||||
|
||||
for (Double value : array) {
|
||||
sum += value;
|
||||
}
|
||||
return sum / array.size();
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import info.nightscout.androidaps.db.BgReading;
|
|||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||
|
|
|
@ -131,6 +131,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class);
|
||||
database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_BOLUS_IDS + "\", " + System.currentTimeMillis() + " " +
|
||||
"WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_BOLUS_IDS + "\")");
|
||||
database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_PUMP_IDS + "\", " + System.currentTimeMillis() + " " +
|
||||
"WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_PUMP_IDS + "\")");
|
||||
} catch (SQLException e) {
|
||||
log.error("Can't create database", e);
|
||||
throw new RuntimeException(e);
|
||||
|
@ -151,6 +155,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class);
|
||||
database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_BOLUS_IDS + "\", " + System.currentTimeMillis() + " " +
|
||||
"WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_BOLUS_IDS + "\")");
|
||||
database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_PUMP_IDS + "\", " + System.currentTimeMillis() + " " +
|
||||
"WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_PUMP_IDS + "\")");
|
||||
} else {
|
||||
log.info(DatabaseHelper.class.getName(), "onUpgrade");
|
||||
TableUtils.dropTable(connectionSource, TempTarget.class, true);
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
|
|
|
@ -17,7 +17,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
|
|
|
@ -39,7 +39,7 @@ import java.util.List;
|
|||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
|
|
|
@ -56,7 +56,7 @@ import info.nightscout.androidaps.Constants;
|
|||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.QuickWizardEntry;
|
||||
|
|
|
@ -18,7 +18,7 @@ import java.text.DecimalFormat;
|
|||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.utils.NumberPicker;
|
||||
|
|
|
@ -74,6 +74,7 @@ public class Notification {
|
|||
public static final int DST_LOOP_DISABLED = 49;
|
||||
public static final int DST_IN_24H = 50;
|
||||
public static final int DISKFULL = 51;
|
||||
public static final int OLDVERSION = 52;
|
||||
|
||||
|
||||
public int id;
|
||||
|
|
|
@ -20,7 +20,7 @@ import info.nightscout.androidaps.Constants;
|
|||
import info.nightscout.androidaps.MainActivity;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
|
|
|
@ -20,7 +20,7 @@ import info.nightscout.androidaps.Constants;
|
|||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
package info.nightscout.androidaps.plugins.general.versionChecker
|
||||
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||
import info.nightscout.androidaps.utils.SP
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Usually we would have a class here.
|
||||
* Instead of having a class we can use an object directly inherited from PluginBase.
|
||||
* This is a lazy loading singleton only loaded when actually used.
|
||||
* */
|
||||
|
||||
object VersionCheckerPlugin : PluginBase(PluginDescription()
|
||||
.mainType(PluginType.CONSTRAINTS)
|
||||
.neverVisible(true)
|
||||
.alwaysEnabled(true)
|
||||
.showInList(false)
|
||||
.pluginName(R.string.versionChecker)), ConstraintsInterface {
|
||||
|
||||
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
checkWarning()
|
||||
checkUpdate()
|
||||
return if (isOldVersion(GRACE_PERIOD_VERY_OLD))
|
||||
value.set(false, MainApp.gs(R.string.very_old_version), this)
|
||||
else
|
||||
value
|
||||
}
|
||||
|
||||
private fun checkWarning() {
|
||||
val now = System.currentTimeMillis()
|
||||
if (isOldVersion(GRACE_PERIOD_WARNING) && shouldWarnAgain(now)) {
|
||||
// store last notification time
|
||||
SP.putLong(R.string.key_last_versionchecker_warning, now)
|
||||
|
||||
//notify
|
||||
val message = MainApp.gs(R.string.new_version_warning, Math.round(now / TimeUnit.DAYS.toMillis(1).toDouble()))
|
||||
val notification = Notification(Notification.OLDVERSION, message, Notification.NORMAL)
|
||||
MainApp.bus().post(EventNewNotification(notification))
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkUpdate() {
|
||||
val now = System.currentTimeMillis()
|
||||
if (shouldCheckVersionAgain(now)) {
|
||||
// store last notification time
|
||||
SP.putLong(R.string.key_last_versioncheck, now)
|
||||
|
||||
checkVersion()
|
||||
}
|
||||
}
|
||||
|
||||
private fun shouldCheckVersionAgain(now: Long) =
|
||||
now > SP.getLong(R.string.key_last_versioncheck, 0) + CHECK_EVERY
|
||||
|
||||
private fun shouldWarnAgain(now: Long) =
|
||||
now > SP.getLong(R.string.key_last_versionchecker_warning, 0) + WARN_EVERY
|
||||
|
||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> =
|
||||
if (isOldVersion(GRACE_PERIOD_OLD))
|
||||
maxIob.set(0.toDouble(), MainApp.gs(R.string.old_version), this)
|
||||
else
|
||||
maxIob
|
||||
|
||||
private fun isOldVersion(gracePeriod: Long): Boolean {
|
||||
val now = System.currentTimeMillis()
|
||||
return now > SP.getLong(R.string.key_new_version_available_since, 0) + gracePeriod
|
||||
}
|
||||
|
||||
val CHECK_EVERY = TimeUnit.DAYS.toMillis(1)
|
||||
val WARN_EVERY = TimeUnit.DAYS.toMillis(1)
|
||||
val GRACE_PERIOD_WARNING = TimeUnit.DAYS.toMillis(30)
|
||||
val GRACE_PERIOD_OLD = TimeUnit.DAYS.toMillis(60)
|
||||
val GRACE_PERIOD_VERY_OLD = TimeUnit.DAYS.toMillis(90)
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package info.nightscout.androidaps.plugins.general.versionChecker
|
||||
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
import info.nightscout.androidaps.BuildConfig
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.L
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||
import info.nightscout.androidaps.utils.SP
|
||||
import org.apache.http.HttpResponse
|
||||
import org.apache.http.client.methods.HttpGet
|
||||
import org.apache.http.impl.client.DefaultHttpClient
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
// check network connection
|
||||
fun isConnected(): Boolean {
|
||||
val connMgr = MainApp.instance().applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
return connMgr.activeNetworkInfo?.isConnected ?: false
|
||||
}
|
||||
|
||||
// convert inputstream to String
|
||||
@Throws(IOException::class)
|
||||
inline fun InputStream.findVersion(): String? {
|
||||
val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)".toRegex()
|
||||
return bufferedReader()
|
||||
.readLines()
|
||||
.filter { regex.matches(it) }
|
||||
.mapNotNull { regex.matchEntire(it)?.groupValues?.getOrNull(3) }
|
||||
.firstOrNull()
|
||||
}
|
||||
|
||||
private val log = LoggerFactory.getLogger(L.CORE)
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
fun checkVersion() = if (isConnected()) {
|
||||
Thread {
|
||||
try {
|
||||
val request = HttpGet("https://raw.githubusercontent.com/MilosKozak/AndroidAPS/master/app/build.gradle")
|
||||
val response: HttpResponse = DefaultHttpClient().execute(request)
|
||||
val version: String? = response.entity.content?.findVersion()
|
||||
compareWithCurrentVersion(version, BuildConfig.VERSION_NAME)
|
||||
} catch (e: IOException) {
|
||||
log.debug("Github master version check error: $e")
|
||||
}
|
||||
}.start()
|
||||
} else
|
||||
log.debug("Github master version no checked. No connectivity")
|
||||
|
||||
fun compareWithCurrentVersion(newVersion: String?, currentVersion: String) {
|
||||
val comparison: Int? = newVersion?.versionStrip()?.compareTo(currentVersion.versionStrip())
|
||||
when {
|
||||
comparison == null -> onVersionNotDetectable()
|
||||
comparison == 0 -> onSameVersionDetected()
|
||||
comparison > 0 -> onNewVersionDetected(currentVersion = currentVersion, newVersion = newVersion)
|
||||
else -> log.debug("Version newer than master. Are you developer?")
|
||||
}
|
||||
}
|
||||
|
||||
fun onSameVersionDetected() {
|
||||
SP.remove(R.string.key_new_version_available_since)
|
||||
}
|
||||
|
||||
fun onVersionNotDetectable() {
|
||||
log.debug("fetch failed, ignore and smartcast to non-null")
|
||||
}
|
||||
|
||||
fun onNewVersionDetected(currentVersion: String, newVersion: String?) {
|
||||
log.debug("Version ${currentVersion} outdated. Found $newVersion")
|
||||
val notification = Notification(Notification.NEWVERSIONDETECTED, String.format(MainApp.gs(R.string.versionavailable), newVersion.toString()), Notification.LOW)
|
||||
MainApp.bus().post(EventNewNotification(notification))
|
||||
SP.putLong(R.string.key_new_version_available_since, System.currentTimeMillis())
|
||||
}
|
||||
|
||||
fun String.versionStrip() = this.mapNotNull {
|
||||
when (it) {
|
||||
in '0'..'9' -> it
|
||||
'.' -> it
|
||||
else -> null
|
||||
}
|
||||
}.joinToString(separator = "")
|
|
@ -32,17 +32,11 @@ import com.google.android.gms.wearable.PutDataRequest;
|
|||
import com.google.android.gms.wearable.Wearable;
|
||||
import com.google.android.gms.wearable.WearableListenerService;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
|
@ -55,15 +49,11 @@ import info.nightscout.androidaps.interfaces.PluginType;
|
|||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
|
||||
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
|
||||
import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.treatments.Treatment;
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
import info.nightscout.androidaps.utils.SafeParse;
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
package info.nightscout.androidaps.plugins.iob.iobCobCalculator;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||
import info.nightscout.androidaps.utils.Round;
|
||||
|
||||
/**
|
||||
* Created by mike on 04.01.2017.
|
||||
*/
|
||||
|
||||
public class GlucoseStatus {
|
||||
private static Logger log = LoggerFactory.getLogger(GlucoseStatus.class);
|
||||
public double glucose = 0d;
|
||||
public double delta = 0d;
|
||||
public double avgdelta = 0d;
|
||||
public double short_avgdelta = 0d;
|
||||
public double long_avgdelta = 0d;
|
||||
public long date = 0L;
|
||||
|
||||
|
||||
public String log() {
|
||||
return "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " +
|
||||
"Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" +
|
||||
"Short avg. delta: " + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl " +
|
||||
"Long avg. delta: " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl";
|
||||
}
|
||||
|
||||
public GlucoseStatus() {
|
||||
}
|
||||
|
||||
public GlucoseStatus round() {
|
||||
this.glucose = Round.roundTo(this.glucose, 0.1);
|
||||
this.delta = Round.roundTo(this.delta, 0.01);
|
||||
this.avgdelta = Round.roundTo(this.avgdelta, 0.01);
|
||||
this.short_avgdelta = Round.roundTo(this.short_avgdelta, 0.01);
|
||||
this.long_avgdelta = Round.roundTo(this.long_avgdelta, 0.01);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static GlucoseStatus getGlucoseStatusData() {
|
||||
return getGlucoseStatusData(false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) {
|
||||
// load 45min
|
||||
//long fromtime = DateUtil.now() - 60 * 1000L * 45;
|
||||
//List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false);
|
||||
|
||||
synchronized (IobCobCalculatorPlugin.getPlugin().getDataLock()) {
|
||||
|
||||
List<BgReading> data = IobCobCalculatorPlugin.getPlugin().getBgReadings();
|
||||
|
||||
if (data == null) {
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug("data=null");
|
||||
return null;
|
||||
}
|
||||
|
||||
int sizeRecords = data.size();
|
||||
if (sizeRecords == 0) {
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug("sizeRecords==0");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (data.get(0).date < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug("olddata");
|
||||
return null;
|
||||
}
|
||||
|
||||
BgReading now = data.get(0);
|
||||
long now_date = now.date;
|
||||
double change;
|
||||
|
||||
if (sizeRecords == 1) {
|
||||
GlucoseStatus status = new GlucoseStatus();
|
||||
status.glucose = now.value;
|
||||
status.short_avgdelta = 0d;
|
||||
status.delta = 0d;
|
||||
status.long_avgdelta = 0d;
|
||||
status.avgdelta = 0d; // for OpenAPS MA
|
||||
status.date = now_date;
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug("sizeRecords==1");
|
||||
return status.round();
|
||||
}
|
||||
|
||||
ArrayList<Double> now_value_list = new ArrayList<>();
|
||||
ArrayList<Double> last_deltas = new ArrayList<>();
|
||||
ArrayList<Double> short_deltas = new ArrayList<>();
|
||||
ArrayList<Double> long_deltas = new ArrayList<>();
|
||||
|
||||
// Use the latest sgv value in the now calculations
|
||||
now_value_list.add(now.value);
|
||||
|
||||
for (int i = 1; i < sizeRecords; i++) {
|
||||
if (data.get(i).value > 38) {
|
||||
BgReading then = data.get(i);
|
||||
long then_date = then.date;
|
||||
double avgdelta;
|
||||
long minutesago;
|
||||
|
||||
minutesago = Math.round((now_date - then_date) / (1000d * 60));
|
||||
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
|
||||
change = now.value - then.value;
|
||||
avgdelta = change / minutesago * 5;
|
||||
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug(then.toString() + " minutesago=" + minutesago + " avgdelta=" + avgdelta);
|
||||
|
||||
// use the average of all data points in the last 2.5m for all further "now" calculations
|
||||
if (0 < minutesago && minutesago < 2.5) {
|
||||
// Keep and average all values within the last 2.5 minutes
|
||||
now_value_list.add(then.value);
|
||||
now.value = average(now_value_list);
|
||||
// short_deltas are calculated from everything ~5-15 minutes ago
|
||||
} else if (2.5 < minutesago && minutesago < 17.5) {
|
||||
//console.error(minutesago, avgdelta);
|
||||
short_deltas.add(avgdelta);
|
||||
// last_deltas are calculated from everything ~5 minutes ago
|
||||
if (2.5 < minutesago && minutesago < 7.5) {
|
||||
last_deltas.add(avgdelta);
|
||||
}
|
||||
// long_deltas are calculated from everything ~20-40 minutes ago
|
||||
} else if (17.5 < minutesago && minutesago < 42.5) {
|
||||
long_deltas.add(avgdelta);
|
||||
} else {
|
||||
// Do not process any more records after >= 42.5 minutes
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GlucoseStatus status = new GlucoseStatus();
|
||||
status.glucose = now.value;
|
||||
status.date = now_date;
|
||||
|
||||
status.short_avgdelta = average(short_deltas);
|
||||
|
||||
if (last_deltas.isEmpty()) {
|
||||
status.delta = status.short_avgdelta;
|
||||
} else {
|
||||
status.delta = average(last_deltas);
|
||||
}
|
||||
|
||||
status.long_avgdelta = average(long_deltas);
|
||||
status.avgdelta = status.short_avgdelta; // for OpenAPS MA
|
||||
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug(status.log());
|
||||
return status.round();
|
||||
}
|
||||
}
|
||||
|
||||
public static double average(ArrayList<Double> array) {
|
||||
double sum = 0d;
|
||||
|
||||
if (array.size() == 0)
|
||||
return 0d;
|
||||
|
||||
for (Double value : array) {
|
||||
sum += value;
|
||||
}
|
||||
return sum / array.size();
|
||||
}
|
||||
}
|
|
@ -65,7 +65,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
private volatile List<BgReading> bgReadings = null; // newest at index 0
|
||||
private volatile List<BgReading> bucketed_data = null;
|
||||
|
||||
final Object dataLock = new Object();
|
||||
private final Object dataLock = new Object();
|
||||
|
||||
boolean stopCalculationTrigger = false;
|
||||
private Thread thread = null;
|
||||
|
@ -108,6 +108,10 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
return bucketed_data;
|
||||
}
|
||||
|
||||
public Object getDataLock() {
|
||||
return dataLock;
|
||||
}
|
||||
|
||||
// roundup to whole minute
|
||||
public static long roundUpTime(long time) {
|
||||
if (time % 60000 == 0)
|
||||
|
|
|
@ -96,7 +96,7 @@ public class IobCobOref1Thread extends Thread {
|
|||
|
||||
long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable);
|
||||
|
||||
synchronized (iobCobCalculatorPlugin.dataLock) {
|
||||
synchronized (iobCobCalculatorPlugin.getDataLock()) {
|
||||
if (bgDataReload) {
|
||||
iobCobCalculatorPlugin.loadBgData(end);
|
||||
iobCobCalculatorPlugin.createBucketedData();
|
||||
|
|
|
@ -95,7 +95,7 @@ public class IobCobThread extends Thread {
|
|||
|
||||
long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable);
|
||||
|
||||
synchronized (iobCobCalculatorPlugin.dataLock) {
|
||||
synchronized (iobCobCalculatorPlugin.getDataLock()) {
|
||||
if (bgDataReload) {
|
||||
iobCobCalculatorPlugin.loadBgData(end);
|
||||
iobCobCalculatorPlugin.createBucketedData();
|
||||
|
|
|
@ -75,8 +75,11 @@ public class AlarmSoundService extends Service {
|
|||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
player.stop();
|
||||
player.release();
|
||||
if (player != null) {
|
||||
player.stop();
|
||||
player.release();
|
||||
}
|
||||
|
||||
if (L.isEnabled(L.CORE))
|
||||
log.debug("onDestroy");
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package info.nightscout.androidaps.utils;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
package info.nightscout.androidaps.utils;
|
||||
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||
|
||||
import static android.content.Context.CONNECTIVITY_SERVICE;
|
||||
|
||||
public class VersionChecker {
|
||||
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||
|
||||
public static void check() {
|
||||
if (isConnected())
|
||||
new Thread(() -> {
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpGet request = new HttpGet("https://raw.githubusercontent.com/MilosKozak/AndroidAPS/master/app/build.gradle");
|
||||
HttpResponse response;
|
||||
|
||||
try {
|
||||
response = client.execute(request);
|
||||
InputStream inputStream = response.getEntity().getContent();
|
||||
|
||||
if (inputStream != null) {
|
||||
String result = findLine(inputStream);
|
||||
if (result != null) {
|
||||
int compare = result.compareTo(BuildConfig.VERSION_NAME.replace("\"", ""));
|
||||
if (compare == 0) {
|
||||
log.debug("Version equal to master");
|
||||
return;
|
||||
} else if (compare > 0) {
|
||||
log.debug("Version outdated. Found " + result);
|
||||
Notification notification = new Notification(Notification.NEWVERSIONDETECTED, String.format(MainApp.gs(R.string.versionavailable), result), Notification.LOW);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
return;
|
||||
} else {
|
||||
log.debug("Version newer than master. Are you developer?");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("Github master version not found");
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.debug("Github master version check error");
|
||||
}
|
||||
}).start();
|
||||
else
|
||||
log.debug("Github master version no checked. No connectivity");
|
||||
}
|
||||
|
||||
// convert inputstream to String
|
||||
private static String findLine(InputStream inputStream) throws IOException {
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
String line;
|
||||
String regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)";
|
||||
Pattern p = Pattern.compile(regex);
|
||||
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
Matcher m = p.matcher(line);
|
||||
if (m.matches()) {
|
||||
log.debug("+++ " + line);
|
||||
return m.group(3);
|
||||
} else {
|
||||
log.debug("--- " + line);
|
||||
}
|
||||
}
|
||||
inputStream.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
// check network connection
|
||||
public static boolean isConnected() {
|
||||
ConnectivityManager connMgr = (ConnectivityManager) MainApp.instance().getApplicationContext().getSystemService(CONNECTIVITY_SERVICE);
|
||||
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
|
||||
return networkInfo != null && networkInfo.isConnected();
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
<string name="nav_resetdb">Reinicializar base de dados</string>
|
||||
<string name="reset_db_confirm">Quer realmente reiniciar a base de dados?</string>
|
||||
<string name="nav_exit">Sair</string>
|
||||
<string name="danar_useextended_title">Usar bólus prolongado de >200%%</string>
|
||||
<string name="danar_bt_name_title">Dispositivo Bluetooth DanaR</string>
|
||||
<string name="ns_sync_use_absolute_title">Usar sempre valores absolutos de basal</string>
|
||||
<string name="alert_dialog_storage_permission_text">Por favor, reinicie o seu telefone ou reinicie o AndroidAPS a partir das Configurações do Sistema \ncaso contrário, o AndroidAPS não terá registro (importante para controlar e verificar se os algoritmos estão a funcionar corretamente)!</string>
|
||||
|
@ -313,6 +314,7 @@
|
|||
<string name="overview_bolusprogress_stop">Parar</string>
|
||||
<string name="overview_bolusprogress_stoppressed">STOP PRESSIONADO</string>
|
||||
<string name="waitingforpump">À espera da bomba</string>
|
||||
<string name="overview_bolusprogress_goingtodeliver">Vão ser administradas %1$.2fU</string>
|
||||
<string name="objectives_0_objective">Configuração da visualização e monitoramento, e análise de rácios e basals</string>
|
||||
<string name="objectives_0_gate">Verificar se a BG está disponível no Nightscout, e se os dados de insulina da bomba estão a ser carregados</string>
|
||||
<string name="objectives_1_objective">A iniciar um open loop</string>
|
||||
|
@ -335,11 +337,23 @@
|
|||
<string name="smscommunicator_loopisdisabled">Loop desactivado</string>
|
||||
<string name="smscommunicator_loopisenabled">Loop activado</string>
|
||||
<string name="valuelimitedto">%1$.2f limitado a %2$.2f</string>
|
||||
<string name="valueoutofrange">O valor %1$s está fora dos limites permitidos</string>
|
||||
<string name="smscommunicator_remotecommandnotallowed">O comando remoto não é permitido</string>
|
||||
<string name="smscommunicator_remotebolusnotallowed">O bólus remoto não está disponível. Tente novamente mais tarde.</string>
|
||||
<string name="smscommunicator_basalreplywithcode">Para começar a basal %1$.2fU/h durante%2$d min responda com o código %3$s</string>
|
||||
<string name="smscommunicator_profilereplywithcode">Para mudar o perfil para %1$s %2$d%% responda com o código %3$s</string>
|
||||
<string name="smscommunicator_extendedreplywithcode">Para começar o bólus estendido %1$.2fU/h para %2$d min responda com o código %3$s</string>
|
||||
<string name="smscommunicator_basalpctreplywithcode">Para começar a basal %1$d% U/h durante %2$d min responda com o código %3$s</string>
|
||||
<string name="smscommunicator_suspendreplywithcode">Para suspender o loop por %1$d minutos resposta com código %2$s</string>
|
||||
<string name="smscommunicator_tempbasalset">Basal temporária %1$.2fU/h para %2$d min iniciada com êxito</string>
|
||||
<string name="smscommunicator_extendedset">Bólus estendido %1$.2fU/h para %2$d min iniciado com êxito</string>
|
||||
<string name="smscommunicator_tempbasalset_percent">Basal temporária %1$d% U/h durante%2$d min iniciada com êxito</string>
|
||||
<string name="smscommunicator_tempbasalfailed">Início basal temp falhou </string>
|
||||
<string name="smscommunicator_extendedfailed">Falha ao iniciar o bólus estendido</string>
|
||||
<string name="smscommunicator_basalstopreplywithcode">Para parar a basal temporária responda com o código %1$s</string>
|
||||
<string name="smscommunicator_extendedstopreplywithcode">Para parar o bólus temporário responda com o código %1$s</string>
|
||||
<string name="smscommunicator_tempbasalcanceled">Basal temp cancelada</string>
|
||||
<string name="smscommunicator_extendedcanceled">Bólus estendido cancelado</string>
|
||||
<string name="smscommunicator_tempbasalcancelfailed">Não foi possivel cancelar a basal temp</string>
|
||||
<string name="smscommunicator_extendedcancelfailed">Falhou o cancelamento do bolus extendido</string>
|
||||
<string name="smscommunicator_unknowncommand">Comando desconhecido ou resposta errada</string>
|
||||
|
@ -450,6 +464,7 @@
|
|||
<string name="profile">Perfil</string>
|
||||
<string name="openapsama_max_daily_safety_multiplier_summary">Valor padrão: 3 Por segurança é o valor limite estabelecido por OpenAPS. O que faz é limitar a basal a x3 a basal mázima. Se necessário modificar este valor, por favor ter em conta que os dados apontam para que os limites de segurança sejam - 3 x max diario ou 4x valor actual (qual seja menor) como valores máximos.</string>
|
||||
<string name="openapsama_current_basal_safety_multiplier_summary">Valor padrão: 4 Esta é a outra parte dos valores limites de segurança - 3 x max diário ou 4x valor actual - do OpenAPS. Isto define que não importa o valor da basal máxima definido na bomba, o valor máximo da basal temporária não pode ser maior que 4 x o valor da basal definida na bomba. O objectivo é evitar que sejam determinadas basais temporárias demasiado elevadas antes que se perceba como o algoritmo funciona. 4x é um valor que a maior parte das pessoas nunca necessitará de alterar pois o mais provável é necessitar de alterar outras definições para não necessitar de \"ultrapassar\" este limite de segurança.</string>
|
||||
<string name="openapsama_autosens_max_summary">Valor predefinido: 1.2\n Este é um multiplicador para autosens (e em breve autotune) que coloca um limite máximo de 20%% aos rácios superiores e inferiores de autosens, o que por sua vez calcula o quão alto autosens pode ajustar a basal, quão pode baixar o Factor de Sensibilidade (FSI) e baixar o valor alvo de glicose no sangue.</string>
|
||||
<string name="openapsama_autosens_min_summary">Valor padrão: 0.7\nO outro lado dos limites de segurança do autosens. Coloca um tecto no quão baixo autosens pode ajustar as basais, e quão alto pode ajustar os valores de ISF e valor alvo de glucose no sangue (BG).</string>
|
||||
<string name="openapsama_autosens_adjusttargets">Autosens também ajusta os alvos</string>
|
||||
<string name="openapsama_autosens_adjusttargets_summary">Valor padrão: true\nÉ usado para permitir que autosens possa ajustar os valores alvo de glucose no sangue (BG), além de ISF e basais.</string>
|
||||
|
@ -462,6 +477,7 @@
|
|||
<string name="error_phone_not_valid">Número de telefone não é válido</string>
|
||||
<string name="smscommunicator_invalidphonennumber">SMS número de telefone inválido</string>
|
||||
<string name="overview_calibration">Calibração</string>
|
||||
<string name="send_calibration">Enviar calibração %1$.1f para o xDrip?</string>
|
||||
<string name="xdripnotinstalled">xDrip+ não está instalado</string>
|
||||
<string name="calibrationsent">Calibração enviada para o xDrip</string>
|
||||
<string name="smscommunicator_calibrationsent">Calibração enviada. Recepção têm de estar activada no xDrip.</string>
|
||||
|
@ -602,6 +618,7 @@
|
|||
<string name="absorptionsettings_title">Configurações de absorção</string>
|
||||
<string name="absorption_maxtime_title">Tempo máx. absorção refeição [h]</string>
|
||||
<string name="absorption_maxtime_summary">Tempo em horas, espectável para que todos os hidratos de carbono da refeição sejam absorvidos</string>
|
||||
<string name="danar_visualizeextendedaspercentage_title">Visualizar bólus prolongado como %%</string>
|
||||
<string name="careportal_sensorage_label_short">SAGE</string>
|
||||
<string name="careportal_insulinage_label_short">IAGE</string>
|
||||
<string name="careportal_canulaage_label_short">CAGE</string>
|
||||
|
@ -714,6 +731,8 @@
|
|||
<string name="dexcomg5_xdripupload_title">Enviar dados Glic. para xDrip+</string>
|
||||
<string name="dexcomg5_xdripupload_summary">Seleccionar 640g/Eversense como fonte no xDrip+</string>
|
||||
<string name="nsclientbg">Glic NSCliente</string>
|
||||
<string name="minimalbasalvaluereplaced">Valor da basal alterado para o valor mínimo suportado: %1$s</string>
|
||||
<string name="maximumbasalvaluereplaced">Valor da basal alterado para o valor máximo suportado: %1$s</string>
|
||||
<string name="overview_editquickwizard_usebg">Cálculos Glic</string>
|
||||
<string name="overview_editquickwizard_usebolusiob">Cálculo de Bólus IOB</string>
|
||||
<string name="overview_editquickwizard_usebasaliob">Cálculo de Basal IOB</string>
|
||||
|
@ -731,6 +750,8 @@
|
|||
<string name="closedmodeenabled">Modo fechado ativado</string>
|
||||
<string name="maxiobset">IOB máxima definida correctamente</string>
|
||||
<string name="hasbgdata">Glicemia disponivel desde a fonte selecionada</string>
|
||||
<string name="basalprofilenotaligned">Valores das basais não definidos por horas: %1$s</string>
|
||||
<string name="zerovalueinprofile">Perfil inválido: %1$s</string>
|
||||
<string name="combo_programming_bolus">A programar a bomba para injectar o bolus</string>
|
||||
<string name="combo_refresh">Actualizar</string>
|
||||
<string name="combo_pump_state_label">Estado</string>
|
||||
|
@ -1072,6 +1093,7 @@
|
|||
<string name="log_operating_mode_changes">Alterações do modo de funcionamento de registo</string>
|
||||
<string name="log_alerts">Alertas de registo</string>
|
||||
<string name="enable_tbr_emulation">Ativar a emulação TBR</string>
|
||||
<string name="enable_tbr_emulation_summary">Usar bólus prolongados em vez de basais temporárias para contornar o limite de 250%%</string>
|
||||
<string name="disconnect_delay">Atraso de desconexão [s]</string>
|
||||
<string name="serial_number">Número de série</string>
|
||||
<string name="release_software_version">Lançar versão de software</string>
|
||||
|
@ -1111,11 +1133,13 @@
|
|||
<string name="short_status_tbr">Basal temporária: %1$d%% para %2$d / %3$d minutos</string>
|
||||
<string name="short_status_extended">Estendido: %1$.2f / %2$.2f U por %3$d min</string>
|
||||
<string name="short_status_multiwave">Multionda: %1$.2f / %2$.2f U por %3$d min</string>
|
||||
<string name="short_status_tdd">TDD: %1$.2f</string>
|
||||
<string name="short_status_reservoir">Reser:%1$.2fU</string>
|
||||
<string name="short_status_battery">Bat.: %1$d%%</string>
|
||||
<string name="max_recovery_duration">Duração máxima da recuperação [s]</string>
|
||||
<string name="min_recovery_duration">Duração mínima da recuperação [s]</string>
|
||||
<string name="recovery_duration">Duração da recuperação</string>
|
||||
<string name="timeout_during_handshake">Tempo de operação excedido - reset bluetooth</string>
|
||||
<string name="profile_total">== ∑ %1$s U</string>
|
||||
<string name="profile_ins_units_per_hout">U/h</string>
|
||||
<string name="profile_carbs_per_unit">g/U</string>
|
||||
|
@ -1124,6 +1148,8 @@
|
|||
<string name="dexcom_lognssensorchange_summary">Criar evento \"Mudança de Sensor\" automaticamente no NS aquando do início do sensor</string>
|
||||
<string name="tomato">Tomato (MiaoMiao)</string>
|
||||
<string name="tomato_short">Tomato</string>
|
||||
<string name="dst_in_24h_warning">Horário de Verão em 24h ou menos</string>
|
||||
<string name="dst_loop_disabled_warning">Horário de Verão a menos de 3 horas - Closed Loop desligado</string>
|
||||
<string name="storage">restrição de armazenamento interno</string>
|
||||
<string name="diskfull">Liberte pelo menos %1$d MB do armazenamento interno! Loop desativado!</string>
|
||||
<string name="wrongformat">Formato incorrecto</string>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--Generated by crowdin.com-->
|
||||
<resources>
|
||||
<string name="treatmentssafety_title">Безопасность назначений</string>
|
||||
<string name="treatmentssafety_title">Безопасность терапии</string>
|
||||
<string name="treatmentssafety_maxbolus_title">Макс разрешенный болюс [U] ед.</string>
|
||||
<string name="treatmentssafety_maxcarbs_title">макс разрешенные углеводы (г)</string>
|
||||
<string name="nav_preferences">опции</string>
|
||||
<string name="nav_refreshtreatments">синхронисировать назначения с NS</string>
|
||||
<string name="nav_refreshtreatments">Синхронизировать назначения с NS</string>
|
||||
<string name="nav_resetdb">обнулить базы</string>
|
||||
<string name="reset_db_confirm">Вы действительно хотите обнулить базы данных?</string>
|
||||
<string name="nav_exit">Выход</string>
|
||||
|
@ -116,7 +116,7 @@
|
|||
<string name="nsprofile">профиль NS</string>
|
||||
<string name="simpleprofile">простой профиль</string>
|
||||
<string name="tempbasal">ВремБазал</string>
|
||||
<string name="treatments">назначения</string>
|
||||
<string name="treatments">Терапия</string>
|
||||
<string name="virtualpump">виртуальная помпа</string>
|
||||
<string name="careportal">Портал лечения / назначений</string>
|
||||
<string name="configbuilder_pump">помпа</string>
|
||||
|
@ -154,7 +154,7 @@
|
|||
<string name="overview_calculator_label">калькулятор</string>
|
||||
<string name="constraintapllied">применено ограничение!</string>
|
||||
<string name="confirmation">подтверждение</string>
|
||||
<string name="entertreatmentquestion">введите новое назначение</string>
|
||||
<string name="entertreatmentquestion">Ввести новое назначение:</string>
|
||||
<string name="bolus">болюс</string>
|
||||
<string name="sms_bolus">болюс:</string>
|
||||
<string name="basal">базал</string>
|
||||
|
@ -690,7 +690,7 @@
|
|||
<string name="gettingpumptime">Получение времени помпы</string>
|
||||
<string name="reuse">повторное использование</string>
|
||||
<string name="wearcontrol_title">Контроль с часов</string>
|
||||
<string name="wearcontrol_summary">Поставить временные цели и ввести назначения с часов.</string>
|
||||
<string name="wearcontrol_summary">Ставить временные цели и вводить назначения с часов.</string>
|
||||
<string name="connectiontimedout">Истекло время ожидания соединения</string>
|
||||
<string name="food">Еда</string>
|
||||
<string name="shortgramm">грамм</string>
|
||||
|
@ -1044,7 +1044,7 @@ Context | Edit Context</string>
|
|||
<string name="careportal_removestartedevents">AndroidAPS перезапущен</string>
|
||||
<string name="storedsettingsfound">Найдены сохраненные параметры</string>
|
||||
<string name="allow_hardware_pump_text">Внимание: Если вы активируете подключение к невиртуальной помпе, AndroidAPS скопирует настройки базала в профиль помпы, перезаписывая существующие настройки, хранящиеся в ней. Убедитесь, что настройки базала в AndroidAPS корректны. Если вы не уверены или не хотите перезаписать настройки базала на помпу, нажмите отменить и повторите подключение в другое время.</string>
|
||||
<string name="error_adding_treatment_title">Данные назначений неполные</string>
|
||||
<string name="error_adding_treatment_title">Данные терапии неполные</string>
|
||||
<string name="maintenance_settings">Параметры обслуживания</string>
|
||||
<string name="maintenance_email">Адрес электронной почты</string>
|
||||
<string name="invalid_email_message">Недопустимый e-mail</string>
|
||||
|
|
|
@ -1326,6 +1326,15 @@
|
|||
<string name="sms_wrongcode">Wrong code. Command cancelled.</string>
|
||||
<string name="notconfigured">Not configured</string>
|
||||
<string name="profileswitchcreated">Profile switch created</string>
|
||||
<string name="versionChecker">Version Checker</string>
|
||||
<string name="key_new_version_available_since" translatable="false">new_version_available_since</string>
|
||||
<string name="key_last_versionchecker_warning" translatable="false">last_versionchecker_waring</string>
|
||||
<string name="key_last_versioncheck" translatable="false">key_last_versioncheck</string>
|
||||
|
||||
<string name="old_version">old version</string>
|
||||
<string name="very_old_version">very old version</string>
|
||||
<string name="new_version_warning">New version for at least %1$d days available! Fallback to LGS after 60 days, loop will be disabled after 90 days</string>
|
||||
|
||||
<plurals name="objective_days">
|
||||
<item quantity="one">%1$d day</item>
|
||||
<item quantity="other">%1$d days</item>
|
||||
|
|
|
@ -282,10 +282,13 @@ public class AAPSMocker {
|
|||
PowerMockito.when(ProfileFunctions.getInstance().getProfileName()).thenReturn(TESTPROFILENAME);
|
||||
}
|
||||
|
||||
public static void mockIobCobCalculatorPlugin() {
|
||||
public static IobCobCalculatorPlugin mockIobCobCalculatorPlugin() {
|
||||
PowerMockito.mockStatic(IobCobCalculatorPlugin.class);
|
||||
IobCobCalculatorPlugin iobCobCalculatorPlugin = PowerMockito.mock(IobCobCalculatorPlugin.class);
|
||||
PowerMockito.when(IobCobCalculatorPlugin.getPlugin()).thenReturn(iobCobCalculatorPlugin);
|
||||
Object dataLock = new Object();
|
||||
PowerMockito.when(iobCobCalculatorPlugin.getDataLock()).thenReturn(dataLock);
|
||||
return iobCobCalculatorPlugin;
|
||||
}
|
||||
|
||||
private static MockedBus bus = new MockedBus();
|
||||
|
|
|
@ -289,7 +289,7 @@ public class ConstraintsCheckerTest {
|
|||
//SafetyPlugin
|
||||
when(ConfigBuilderPlugin.getPlugin().getActivePump()).thenReturn(pump);
|
||||
|
||||
constraintChecker = new ConstraintChecker(mainApp);
|
||||
constraintChecker = new ConstraintChecker();
|
||||
|
||||
safetyPlugin = SafetyPlugin.getPlugin();
|
||||
objectivesPlugin = ObjectivesPlugin.getPlugin();
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
package info.nightscout.androidaps.plugins.general.versionChecker
|
||||
|
||||
import com.squareup.otto.Bus
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.L
|
||||
import info.nightscout.androidaps.utils.SP
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers
|
||||
import org.mockito.Mockito.*
|
||||
import org.powermock.api.mockito.PowerMockito
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
||||
import org.powermock.modules.junit4.PowerMockRunner
|
||||
|
||||
|
||||
@RunWith(PowerMockRunner::class)
|
||||
class VersionCheckerUtilsKtTest {
|
||||
@Test
|
||||
fun findVersionMatchesRegularVersion() {
|
||||
val buildGradle = """blabla
|
||||
| android {
|
||||
| aosenuthoae
|
||||
| }
|
||||
| version = "2.2.2"
|
||||
| appName = "Aaoeu"
|
||||
""".trimMargin()
|
||||
val detectedVersion: String? = buildGradle.byteInputStream().findVersion()
|
||||
assertEquals("2.2.2", detectedVersion)
|
||||
}
|
||||
|
||||
|
||||
// In case we merge a "x.x.x-dev" into master, don't see it as update.
|
||||
@Test
|
||||
fun `should return null on non-digit versions on master`() {
|
||||
val buildGradle = """blabla
|
||||
| android {
|
||||
| aosenuthoae
|
||||
| }
|
||||
| version = "2.2.2-nefarious-underground-mod"
|
||||
| appName = "Aaoeu"
|
||||
""".trimMargin()
|
||||
val detectedVersion: String? = buildGradle.byteInputStream().findVersion()
|
||||
assertEquals(null, detectedVersion)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findVersionMatchesDoesNotMatchErrorResponse() {
|
||||
val buildGradle = """<html><body>Balls! No build.gradle here. Move along</body><html>"""
|
||||
val detectedVersion: String? = buildGradle.byteInputStream().findVersion()
|
||||
assertEquals(null, detectedVersion)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testVersionStrip() {
|
||||
assertEquals("2.2.2", "2.2.2".versionStrip())
|
||||
assertEquals("2.2.2", "2.2.2-dev".versionStrip())
|
||||
assertEquals("2.2.2", "2.2.2dev".versionStrip())
|
||||
assertEquals("2.2.2", """"2.2.2"""".versionStrip())
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest(MainApp::class, L::class, SP::class)
|
||||
fun `should find update1`() {
|
||||
val bus = prepareBus()
|
||||
|
||||
compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1")
|
||||
|
||||
verify(bus, times(1)).post(any())
|
||||
|
||||
PowerMockito.verifyStatic(SP::class.java, times(1))
|
||||
SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong())
|
||||
PowerMockito.verifyNoMoreInteractions(SP::class.java)
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest(MainApp::class, L::class, SP::class)
|
||||
fun `should find update2`() {
|
||||
val bus = prepareBus()
|
||||
|
||||
compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1-dev")
|
||||
|
||||
verify(bus, times(1)).post(any())
|
||||
|
||||
PowerMockito.verifyStatic(SP::class.java, times(1))
|
||||
SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong())
|
||||
PowerMockito.verifyNoMoreInteractions(SP::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest(MainApp::class, L::class, SP::class)
|
||||
fun `should find update3`() {
|
||||
val bus = prepareBus()
|
||||
|
||||
compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.1")
|
||||
|
||||
verify(bus, times(1)).post(any())
|
||||
|
||||
PowerMockito.verifyStatic(SP::class.java, times(1))
|
||||
SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong())
|
||||
PowerMockito.verifyNoMoreInteractions(SP::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest(MainApp::class, L::class, SP::class)
|
||||
fun `should find update4`() {
|
||||
val bus = prepareBus()
|
||||
|
||||
compareWithCurrentVersion(newVersion = "2.2", currentVersion = "2.1.1")
|
||||
|
||||
verify(bus, times(1)).post(any())
|
||||
|
||||
PowerMockito.verifyStatic(SP::class.java, times(1))
|
||||
SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong())
|
||||
PowerMockito.verifyNoMoreInteractions(SP::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest(MainApp::class, L::class, SP::class)
|
||||
fun `should find update5`() {
|
||||
val bus = prepareBus()
|
||||
compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2-dev")
|
||||
|
||||
verify(bus, times(1)).post(any())
|
||||
|
||||
PowerMockito.verifyStatic(SP::class.java, times(1))
|
||||
SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong())
|
||||
PowerMockito.verifyNoMoreInteractions(SP::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest(MainApp::class, L::class, SP::class)
|
||||
fun `should find update6`() {
|
||||
val bus = prepareBus()
|
||||
compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2dev")
|
||||
|
||||
verify(bus, times(1)).post(any())
|
||||
|
||||
PowerMockito.verifyStatic(SP::class.java, times(1))
|
||||
SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong())
|
||||
PowerMockito.verifyNoMoreInteractions(SP::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest(MainApp::class, L::class, SP::class)
|
||||
fun `find same version`() {
|
||||
val buildGradle = """blabla
|
||||
| android {
|
||||
| aosenuthoae
|
||||
| }
|
||||
| version = "2.2.2"
|
||||
| appName = "Aaoeu"
|
||||
""".trimMargin()
|
||||
val bus = prepareBus()
|
||||
compareWithCurrentVersion(buildGradle.byteInputStream().findVersion(), currentVersion = "2.2.2")
|
||||
|
||||
verify(bus, times(0)).post(any())
|
||||
|
||||
PowerMockito.verifyStatic(SP::class.java, times(1))
|
||||
SP.remove(eq(R.string.key_new_version_available_since))
|
||||
PowerMockito.verifyNoMoreInteractions(SP::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest(MainApp::class, L::class, SP::class)
|
||||
fun `find higher version`() {
|
||||
val buildGradle = """blabla
|
||||
| android {
|
||||
| aosenuthoae
|
||||
| }
|
||||
| version = "3.0"
|
||||
| appName = "Aaoeu"
|
||||
""".trimMargin()
|
||||
val bus = prepareBus()
|
||||
compareWithCurrentVersion(buildGradle.byteInputStream().findVersion(), currentVersion = "2.2.2")
|
||||
|
||||
verify(bus, times(1)).post(any())
|
||||
|
||||
PowerMockito.verifyStatic(SP::class.java, times(1))
|
||||
SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong())
|
||||
PowerMockito.verifyNoMoreInteractions(SP::class.java)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@PrepareForTest(System::class)
|
||||
fun `set time`() {
|
||||
PowerMockito.spy(System::class.java)
|
||||
PowerMockito.`when`(System.currentTimeMillis()).thenReturn(100L)
|
||||
|
||||
assertEquals(100L, System.currentTimeMillis())
|
||||
}
|
||||
|
||||
private fun prepareBus(): Bus {
|
||||
PowerMockito.mockStatic(MainApp::class.java)
|
||||
val mainApp = mock<MainApp>(MainApp::class.java)
|
||||
`when`(MainApp.instance()).thenReturn(mainApp)
|
||||
val bus = mock(Bus::class.java)
|
||||
`when`(MainApp.bus()).thenReturn(bus)
|
||||
`when`(MainApp.gs(ArgumentMatchers.anyInt())).thenReturn("some dummy string")
|
||||
prepareSP()
|
||||
return bus
|
||||
}
|
||||
|
||||
private fun prepareSP() {
|
||||
PowerMockito.mockStatic(SP::class.java)
|
||||
}
|
||||
|
||||
private fun prepareLogging() {
|
||||
PowerMockito.mockStatic(L::class.java)
|
||||
`when`(L.isEnabled(any())).thenReturn(true)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.data;
|
||||
package info.nightscout.androidaps.plugins.iob.iobCobCalculatorPlugin;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
@ -16,6 +16,7 @@ import java.util.List;
|
|||
import info.AAPSMocker;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
|
@ -133,10 +134,7 @@ public class GlucoseStatusTest {
|
|||
public void initMocking() {
|
||||
AAPSMocker.mockMainApp();
|
||||
AAPSMocker.mockStrings();
|
||||
|
||||
PowerMockito.mockStatic(IobCobCalculatorPlugin.class);
|
||||
iobCobCalculatorPlugin = mock(IobCobCalculatorPlugin.class);
|
||||
when(IobCobCalculatorPlugin.getPlugin()).thenReturn(iobCobCalculatorPlugin);
|
||||
iobCobCalculatorPlugin = AAPSMocker.mockIobCobCalculatorPlugin();
|
||||
|
||||
PowerMockito.mockStatic(DateUtil.class);
|
||||
when(DateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs());
|
|
@ -9,7 +9,7 @@ import org.powermock.modules.junit4.PowerMockRunner;
|
|||
|
||||
import info.AAPSMocker;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.21'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
@ -16,6 +17,7 @@ buildscript {
|
|||
// in the individual module build.gradle files
|
||||
|
||||
classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0-SNAPSHOT'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue