Medtronic 0.8.1-SNAPSHOT
- wear changes - refactoring of decoder - started work on bolus, tbr, resumes
This commit is contained in:
parent
5a8b5f3e7b
commit
6fcb1ce230
29 changed files with 1665 additions and 654 deletions
|
@ -64,7 +64,7 @@ android {
|
|||
multiDexEnabled true
|
||||
versionCode 1500
|
||||
// dev_version: 2.1
|
||||
version "medtronic-0.8.0"
|
||||
version "medtronic-0.8.1-SNAPSHOT"
|
||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||
buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"'
|
||||
|
@ -72,6 +72,7 @@ android {
|
|||
buildConfigField "String", "DEV_DATE", '"2.3.2019"'
|
||||
buildConfigField "String", "DEV_CHECKIN", '"f28d763ada9e6a8d7621b972e03edd980767e076"'
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
// if you change minSdkVersion to less than 11, you need to change executeTask for wear
|
||||
|
||||
ndk {
|
||||
moduleName "BleCommandUtil"
|
||||
|
@ -81,7 +82,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
|
||||
|
@ -103,9 +104,9 @@ android {
|
|||
applicationId "info.nightscout.androidaps"
|
||||
dimension "standard"
|
||||
resValue "string", "app_name", "AndroidAPS"
|
||||
versionName version + "-pumpcontrol"
|
||||
versionName version
|
||||
manifestPlaceholders = [
|
||||
appIcon: "@mipmap/ic_launcher",
|
||||
appIcon : "@mipmap/ic_launcher",
|
||||
appIconRound: "@mipmap/ic_launcher_round"
|
||||
]
|
||||
}
|
||||
|
@ -125,7 +126,7 @@ android {
|
|||
resValue "string", "app_name", "NSClient"
|
||||
versionName version + "-nsclient"
|
||||
manifestPlaceholders = [
|
||||
appIcon: "@mipmap/ic_yellowowl",
|
||||
appIcon : "@mipmap/yellowowl",
|
||||
appIconRound: "@null"
|
||||
]
|
||||
}
|
||||
|
@ -135,7 +136,7 @@ android {
|
|||
resValue "string", "app_name", "NSClient2"
|
||||
versionName version + "-nsclient"
|
||||
manifestPlaceholders = [
|
||||
appIcon: "@mipmap/ic_yellowowl",
|
||||
appIcon : "@mipmap/yellowowl",
|
||||
appIconRound: "@null"
|
||||
]
|
||||
}
|
||||
|
@ -198,7 +199,7 @@ dependencies {
|
|||
implementation "org.slf4j:slf4j-api:1.7.12"
|
||||
implementation "com.jjoe64:graphview:4.0.1"
|
||||
implementation "com.joanzapata.iconify:android-iconify-fontawesome:2.1.1"
|
||||
implementation "com.google.android.gms:play-services-wearable:7.5.0"
|
||||
implementation 'com.google.android.gms:play-services-wearable:10.2.1'
|
||||
implementation(name: "android-edittext-validator-v1.3.4-mod", ext: "aar")
|
||||
implementation(name: "sightparser-release", ext: "aar")
|
||||
implementation 'com.madgag.spongycastle:core:1.58.0.0'
|
||||
|
@ -232,6 +233,8 @@ dependencies {
|
|||
testImplementation "com.google.truth:truth:0.39"
|
||||
testImplementation 'org.robolectric:robolectric:3.8'
|
||||
testImplementation "org.skyscreamer:jsonassert:1.5.0"
|
||||
testImplementation "org.hamcrest:hamcrest-all:1.3"
|
||||
testImplementation "uk.org.lidalia:slf4j-test:1.2.0"
|
||||
|
||||
androidTestImplementation "org.mockito:mockito-core:2.7.22"
|
||||
androidTestImplementation "com.google.dexmaker:dexmaker:${dexmakerVersion}"
|
||||
|
|
|
@ -174,7 +174,63 @@
|
|||
android:name=".plugins.general.wear.wearintegration.WatchUpdaterService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
|
||||
<!-- <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> -->
|
||||
<!-- listeners receive events that match the action and data filters -->
|
||||
<action android:name="com.google.android.gms.wearable.CAPABILITY_CHANGED" />
|
||||
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
|
||||
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_data" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_data_resend" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_cancel_bolus" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_confirmactionstring" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_initiateactionstring" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/openwearsettings" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/sendstatustowear" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/sendpreferencestowear" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_basal" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_bolusprogress" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_actionconfirmationrequest" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_changeconfirmationrequest" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_cancelnotificationrequest" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service
|
||||
|
|
|
@ -1,24 +1,5 @@
|
|||
package info.nightscout.androidaps.db;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
||||
import com.j256.ormlite.dao.CloseableIterator;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
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 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.Calendar;
|
||||
|
@ -30,6 +11,26 @@ import java.util.concurrent.ScheduledExecutorService;
|
|||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
||||
import com.j256.ormlite.dao.CloseableIterator;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
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 info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.data.OverlappingIntervals;
|
||||
|
@ -48,9 +49,9 @@ import info.nightscout.androidaps.events.EventTempTargetChange;
|
|||
import info.nightscout.androidaps.interfaces.ProfileInterface;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
||||
import info.nightscout.androidaps.plugins.pump.danaR.activities.DanaRNSHistorySync;
|
||||
import info.nightscout.androidaps.plugins.pump.danaR.comm.RecordTypes;
|
||||
import info.nightscout.androidaps.plugins.pump.insight.database.InsightBolusID;
|
||||
|
@ -65,9 +66,9 @@ import info.nightscout.androidaps.utils.ToastUtils;
|
|||
* This Helper contains all resource to provide a central DB management functionality. Only methods handling
|
||||
* data-structure (and not the DB content) should be contained in here (meaning DDL and not SQL).
|
||||
* <p>
|
||||
* This class can safely be called from Services, but should not call Services to avoid circular dependencies.
|
||||
* One major issue with this (right now) are the scheduled events, which are put into the service. Therefor all
|
||||
* direct calls to the corresponding methods (eg. resetDatabases) should be done by a central service.
|
||||
* This class can safely be called from Services, but should not call Services to avoid circular dependencies. One major
|
||||
* issue with this (right now) are the scheduled events, which are put into the service. Therefor all direct calls to
|
||||
* the corresponding methods (eg. resetDatabases) should be done by a central service.
|
||||
*/
|
||||
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||
|
||||
|
@ -106,7 +107,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
private static final ScheduledExecutorService careportalEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||
private static ScheduledFuture<?> scheduledCareportalEventPost = null;
|
||||
|
||||
private static final ScheduledExecutorService profileSwitchEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||
private static final ScheduledExecutorService profileSwitchEventWorker = Executors
|
||||
.newSingleThreadScheduledExecutor();
|
||||
private static ScheduledFuture<?> scheduledProfileSwitchEventPost = null;
|
||||
|
||||
private int oldVersion = 0;
|
||||
|
@ -116,7 +118,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
public DatabaseHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
onCreate(getWritableDatabase(), getConnectionSource());
|
||||
//onUpgrade(getWritableDatabase(), getConnectionSource(), 1,1);
|
||||
// onUpgrade(getWritableDatabase(), getConnectionSource(), 1,1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -241,15 +243,13 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
scheduleTemporaryTargetChange();
|
||||
scheduleCareportalEventChange();
|
||||
scheduleProfileSwitchChange();
|
||||
new java.util.Timer().schedule(
|
||||
new java.util.TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
MainApp.bus().post(new EventRefreshOverview("resetDatabases"));
|
||||
}
|
||||
},
|
||||
3000
|
||||
);
|
||||
new java.util.Timer().schedule(new java.util.TimerTask() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
MainApp.bus().post(new EventRefreshOverview("resetDatabases"));
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
|
||||
|
@ -367,18 +367,22 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
return getDao(ProfileSwitch.class);
|
||||
}
|
||||
|
||||
|
||||
private Dao<InsightPumpID, Long> getDaoInsightPumpID() throws SQLException {
|
||||
return getDao(InsightPumpID.class);
|
||||
}
|
||||
|
||||
|
||||
private Dao<InsightBolusID, Long> getDaoInsightBolusID() throws SQLException {
|
||||
return getDao(InsightBolusID.class);
|
||||
}
|
||||
|
||||
|
||||
private Dao<InsightHistoryOffset, String> getDaoInsightHistoryOffset() throws SQLException {
|
||||
return getDao(InsightHistoryOffset.class);
|
||||
}
|
||||
|
||||
|
||||
public static long roundDateToSec(long date) {
|
||||
long rounded = date - date % 1000;
|
||||
if (rounded != date)
|
||||
|
@ -434,6 +438,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
public void run() {
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Firing EventNewBg");
|
||||
Log.d("DatabaseHelper", "WR: Firing EventNewBg");
|
||||
MainApp.bus().post(new EventNewBG(bgReading));
|
||||
scheduledBgPost = null;
|
||||
}
|
||||
|
@ -703,7 +708,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
old.copyFrom(tempTarget);
|
||||
getDaoTempTargets().create(old);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPTARGET: Updating record by date from: " + Source.getString(tempTarget.source) + " " + old.toString());
|
||||
log.debug("TEMPTARGET: Updating record by date from: "
|
||||
+ Source.getString(tempTarget.source) + " " + old.toString());
|
||||
scheduleTemporaryTargetChange();
|
||||
return true;
|
||||
}
|
||||
|
@ -723,7 +729,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
old.copyFrom(tempTarget);
|
||||
getDaoTempTargets().create(old);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPTARGET: Updating record by _id from: " + Source.getString(tempTarget.source) + " " + old.toString());
|
||||
log.debug("TEMPTARGET: Updating record by _id from: "
|
||||
+ Source.getString(tempTarget.source) + " " + old.toString());
|
||||
scheduleTemporaryTargetChange();
|
||||
return true;
|
||||
}
|
||||
|
@ -731,14 +738,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
getDaoTempTargets().create(tempTarget);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " " + tempTarget.toString());
|
||||
log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " "
|
||||
+ tempTarget.toString());
|
||||
scheduleTemporaryTargetChange();
|
||||
return true;
|
||||
}
|
||||
if (tempTarget.source == Source.USER) {
|
||||
getDaoTempTargets().create(tempTarget);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " " + tempTarget.toString());
|
||||
log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " "
|
||||
+ tempTarget.toString());
|
||||
scheduleTemporaryTargetChange();
|
||||
return true;
|
||||
}
|
||||
|
@ -798,14 +807,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
public void createTemptargetFromJsonIfNotExists(JSONObject trJson) {
|
||||
try {
|
||||
String units = JsonHelper.safeGetString(trJson, "units", Constants.MGDL);
|
||||
TempTarget tempTarget = new TempTarget()
|
||||
.date(trJson.getLong("mills"))
|
||||
.duration(trJson.getInt("duration"))
|
||||
.low(Profile.toMgdl(trJson.getDouble("targetBottom"), units))
|
||||
.high(Profile.toMgdl(trJson.getDouble("targetTop"), units))
|
||||
.reason(JsonHelper.safeGetString(trJson, "reason", ""))
|
||||
._id(trJson.getString("_id"))
|
||||
.source(Source.NIGHTSCOUT);
|
||||
TempTarget tempTarget = new TempTarget().date(trJson.getLong("mills")).duration(trJson.getInt("duration"))
|
||||
.low(Profile.toMgdl(trJson.getDouble("targetBottom"), units))
|
||||
.high(Profile.toMgdl(trJson.getDouble("targetTop"), units))
|
||||
.reason(JsonHelper.safeGetString(trJson, "reason", ""))._id(trJson.getString("_id"))
|
||||
.source(Source.NIGHTSCOUT);
|
||||
createOrUpdate(tempTarget);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception: " + trJson.toString(), e);
|
||||
|
@ -849,7 +855,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
try {
|
||||
getDaoDanaRHistory().createOrUpdate(record);
|
||||
|
||||
//If it is a TDD, store it for stats also.
|
||||
// If it is a TDD, store it for stats also.
|
||||
if (record.recordCode == RecordTypes.RECORD_TYPE_DAILY) {
|
||||
createOrUpdateTDD(new TDD(record.recordDate, record.recordDailyBolus, record.recordDailyBasal, 0));
|
||||
}
|
||||
|
@ -906,7 +912,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
// ------------ TemporaryBasal handling ---------------
|
||||
|
||||
//return true if new record was created
|
||||
// return true if new record was created
|
||||
public boolean createOrUpdate(TemporaryBasal tempBasal) {
|
||||
try {
|
||||
TemporaryBasal old;
|
||||
|
@ -922,12 +928,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
if (trList.size() > 0) {
|
||||
// do nothing, pump history record cannot be changed
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: Already exists from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
log.debug("TEMPBASAL: Already exists from: " + Source.getString(tempBasal.source) + " "
|
||||
+ tempBasal.toString());
|
||||
return false;
|
||||
}
|
||||
getDaoTemporaryBasal().create(tempBasal);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " "
|
||||
+ tempBasal.toString());
|
||||
updateEarliestDataChange(tempBasal.date);
|
||||
scheduleTemporaryBasalChange();
|
||||
return true;
|
||||
|
@ -945,7 +953,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
old.copyFrom(tempBasal);
|
||||
getDaoTemporaryBasal().create(old);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: Updating record by date from: " + Source.getString(tempBasal.source) + " " + old.toString());
|
||||
log.debug("TEMPBASAL: Updating record by date from: " + Source.getString(tempBasal.source)
|
||||
+ " " + old.toString());
|
||||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
scheduleTemporaryBasalChange();
|
||||
|
@ -968,7 +977,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
old.copyFrom(tempBasal);
|
||||
getDaoTemporaryBasal().create(old);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: Updating record by _id from: " + Source.getString(tempBasal.source) + " " + old.toString());
|
||||
log.debug("TEMPBASAL: Updating record by _id from: "
|
||||
+ Source.getString(tempBasal.source) + " " + old.toString());
|
||||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
scheduleTemporaryBasalChange();
|
||||
|
@ -978,7 +988,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
getDaoTemporaryBasal().create(tempBasal);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " "
|
||||
+ tempBasal.toString());
|
||||
updateEarliestDataChange(tempBasal.date);
|
||||
scheduleTemporaryBasalChange();
|
||||
return true;
|
||||
|
@ -986,7 +997,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
if (tempBasal.source == Source.USER) {
|
||||
getDaoTemporaryBasal().create(tempBasal);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " "
|
||||
+ tempBasal.toString());
|
||||
updateEarliestDataChange(tempBasal.date);
|
||||
scheduleTemporaryBasalChange();
|
||||
return true;
|
||||
|
@ -1052,31 +1064,28 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
|
||||
/*
|
||||
{
|
||||
"_id": "59232e1ddd032d04218dab00",
|
||||
"eventType": "Temp Basal",
|
||||
"duration": 60,
|
||||
"percent": -50,
|
||||
"created_at": "2017-05-22T18:29:57Z",
|
||||
"enteredBy": "AndroidAPS",
|
||||
"notes": "Basal Temp Start 50% 60.0 min",
|
||||
"NSCLIENT_ID": 1495477797863,
|
||||
"mills": 1495477797000,
|
||||
"mgdl": 194.5,
|
||||
"endmills": 1495481397000
|
||||
}
|
||||
*/
|
||||
* {
|
||||
* "_id": "59232e1ddd032d04218dab00",
|
||||
* "eventType": "Temp Basal",
|
||||
* "duration": 60,
|
||||
* "percent": -50,
|
||||
* "created_at": "2017-05-22T18:29:57Z",
|
||||
* "enteredBy": "AndroidAPS",
|
||||
* "notes": "Basal Temp Start 50% 60.0 min",
|
||||
* "NSCLIENT_ID": 1495477797863,
|
||||
* "mills": 1495477797000,
|
||||
* "mgdl": 194.5,
|
||||
* "endmills": 1495481397000
|
||||
* }
|
||||
*/
|
||||
|
||||
public void createTempBasalFromJsonIfNotExists(JSONObject trJson) {
|
||||
try {
|
||||
if (trJson.has("originalExtendedAmount")) { // extended bolus uploaded as temp basal
|
||||
ExtendedBolus extendedBolus = new ExtendedBolus()
|
||||
.source(Source.NIGHTSCOUT)
|
||||
.date(trJson.getLong("mills"))
|
||||
.pumpId(trJson.has("pumpId") ? trJson.getLong("pumpId") : 0)
|
||||
.durationInMinutes(trJson.getInt("duration"))
|
||||
.insulin(trJson.getDouble("originalExtendedAmount"))
|
||||
._id(trJson.getString("_id"));
|
||||
ExtendedBolus extendedBolus = new ExtendedBolus().source(Source.NIGHTSCOUT)
|
||||
.date(trJson.getLong("mills")).pumpId(trJson.has("pumpId") ? trJson.getLong("pumpId") : 0)
|
||||
.durationInMinutes(trJson.getInt("duration")).insulin(trJson.getDouble("originalExtendedAmount"))
|
||||
._id(trJson.getString("_id"));
|
||||
// if faking found in NS, adapt AAPS to use it too
|
||||
if (!VirtualPumpPlugin.getPlugin().getFakingStatus()) {
|
||||
VirtualPumpPlugin.getPlugin().setFakingStatus(true);
|
||||
|
@ -1100,10 +1109,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
createOrUpdate(extendedBolus);
|
||||
} else {
|
||||
TemporaryBasal tempBasal = new TemporaryBasal()
|
||||
.date(trJson.getLong("mills"))
|
||||
.source(Source.NIGHTSCOUT)
|
||||
.pumpId(trJson.has("pumpId") ? trJson.getLong("pumpId") : 0);
|
||||
TemporaryBasal tempBasal = new TemporaryBasal().date(trJson.getLong("mills")).source(Source.NIGHTSCOUT)
|
||||
.pumpId(trJson.has("pumpId") ? trJson.getLong("pumpId") : 0);
|
||||
if (trJson.has("duration")) {
|
||||
tempBasal.durationInMinutes = trJson.getInt("duration");
|
||||
}
|
||||
|
@ -1162,7 +1169,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
public boolean createOrUpdate(ExtendedBolus extendedBolus) {
|
||||
try {
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: createOrUpdate: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log());
|
||||
log.debug("EXTENDEDBOLUS: createOrUpdate: " + Source.getString(extendedBolus.source) + " "
|
||||
+ extendedBolus.log());
|
||||
|
||||
ExtendedBolus old;
|
||||
extendedBolus.date = roundDateToSec(extendedBolus.date);
|
||||
|
@ -1187,7 +1195,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
getDaoExtendedBolus().createOrUpdate(extendedBolus);
|
||||
}
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log());
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " "
|
||||
+ extendedBolus.log());
|
||||
updateEarliestDataChange(extendedBolus.date);
|
||||
scheduleExtendedBolusChange();
|
||||
return true;
|
||||
|
@ -1201,7 +1210,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
old.copyFrom(extendedBolus);
|
||||
getDaoExtendedBolus().create(old);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: Updating record by date from: " + Source.getString(extendedBolus.source) + " " + old.log());
|
||||
log.debug("EXTENDEDBOLUS: Updating record by date from: "
|
||||
+ Source.getString(extendedBolus.source) + " " + old.log());
|
||||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
scheduleExtendedBolusChange();
|
||||
|
@ -1224,7 +1234,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
old.copyFrom(extendedBolus);
|
||||
getDaoExtendedBolus().create(old);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: Updating record by _id from: " + Source.getString(extendedBolus.source) + " " + old.log());
|
||||
log.debug("EXTENDEDBOLUS: Updating record by _id from: "
|
||||
+ Source.getString(extendedBolus.source) + " " + old.log());
|
||||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
scheduleExtendedBolusChange();
|
||||
|
@ -1234,7 +1245,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
getDaoExtendedBolus().create(extendedBolus);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log());
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " "
|
||||
+ extendedBolus.log());
|
||||
updateEarliestDataChange(extendedBolus.date);
|
||||
scheduleExtendedBolusChange();
|
||||
return true;
|
||||
|
@ -1242,7 +1254,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
if (extendedBolus.source == Source.USER) {
|
||||
getDaoExtendedBolus().create(extendedBolus);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log());
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " "
|
||||
+ extendedBolus.log());
|
||||
updateEarliestDataChange(extendedBolus.date);
|
||||
scheduleExtendedBolusChange();
|
||||
return true;
|
||||
|
@ -1253,17 +1266,17 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
public ExtendedBolus getExtendedBolusByPumpId(long pumpId) {
|
||||
try {
|
||||
return getDaoExtendedBolus().queryBuilder()
|
||||
.where().eq("pumpId", pumpId)
|
||||
.queryForFirst();
|
||||
return getDaoExtendedBolus().queryBuilder().where().eq("pumpId", pumpId).queryForFirst();
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void delete(ExtendedBolus extendedBolus) {
|
||||
try {
|
||||
getDaoExtendedBolus().delete(extendedBolus);
|
||||
|
@ -1326,20 +1339,20 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
|
||||
/*
|
||||
{
|
||||
"_id": "5924898d577eb0880e355337",
|
||||
"eventType": "Combo Bolus",
|
||||
"duration": 120,
|
||||
"splitNow": 0,
|
||||
"splitExt": 100,
|
||||
"enteredinsulin": 1,
|
||||
"relative": 1,
|
||||
"created_at": "2017-05-23T19:12:14Z",
|
||||
"enteredBy": "AndroidAPS",
|
||||
"NSCLIENT_ID": 1495566734628,
|
||||
"mills": 1495566734000,
|
||||
"mgdl": 106
|
||||
}
|
||||
* {
|
||||
* "_id": "5924898d577eb0880e355337",
|
||||
* "eventType": "Combo Bolus",
|
||||
* "duration": 120,
|
||||
* "splitNow": 0,
|
||||
* "splitExt": 100,
|
||||
* "enteredinsulin": 1,
|
||||
* "relative": 1,
|
||||
* "created_at": "2017-05-23T19:12:14Z",
|
||||
* "enteredBy": "AndroidAPS",
|
||||
* "NSCLIENT_ID": 1495566734628,
|
||||
* "mills": 1495566734000,
|
||||
* "mgdl": 106
|
||||
* }
|
||||
*/
|
||||
|
||||
public void createExtendedBolusFromJsonIfNotExists(JSONObject json) {
|
||||
|
@ -1450,7 +1463,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
OverlappingIntervals offlineEvents = new OverlappingIntervals();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
CareportalEvent event = list.get(i);
|
||||
if (!event.eventType.equals(CareportalEvent.OPENAPSOFFLINE)) continue;
|
||||
if (!event.eventType.equals(CareportalEvent.OPENAPSOFFLINE))
|
||||
continue;
|
||||
offlineEvents.add(event);
|
||||
}
|
||||
|
||||
|
@ -1618,11 +1632,13 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
if (old != null) {
|
||||
if (!old.isEqual(profileSwitch)) {
|
||||
profileSwitch.source = old.source;
|
||||
profileSwitch.profileName = old.profileName; // preserver profileName to prevent multiple CPP extension
|
||||
profileSwitch.profileName = old.profileName; // preserver profileName to prevent multiple CPP
|
||||
// extension
|
||||
getDaoProfileSwitch().delete(old); // need to delete/create because date may change too
|
||||
getDaoProfileSwitch().create(profileSwitch);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("PROFILESWITCH: Updating record by date from: " + Source.getString(profileSwitch.source) + " " + old.toString());
|
||||
log.debug("PROFILESWITCH: Updating record by date from: "
|
||||
+ Source.getString(profileSwitch.source) + " " + old.toString());
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
|
@ -1642,7 +1658,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
old.copyFrom(profileSwitch);
|
||||
getDaoProfileSwitch().create(old);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("PROFILESWITCH: Updating record by _id from: " + Source.getString(profileSwitch.source) + " " + old.toString());
|
||||
log.debug("PROFILESWITCH: Updating record by _id from: "
|
||||
+ Source.getString(profileSwitch.source) + " " + old.toString());
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
|
@ -1652,14 +1669,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
profileSwitch.profileName = PercentageSplitter.pureName(profileSwitch.profileName);
|
||||
getDaoProfileSwitch().create(profileSwitch);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString());
|
||||
log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " "
|
||||
+ profileSwitch.toString());
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
if (profileSwitch.source == Source.USER) {
|
||||
getDaoProfileSwitch().create(profileSwitch);
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString());
|
||||
log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " "
|
||||
+ profileSwitch.toString());
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
|
@ -1701,17 +1720,18 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"_id":"592fa43ed97496a80da913d2",
|
||||
"created_at":"2017-06-01T05:20:06Z",
|
||||
"eventType":"Profile Switch",
|
||||
"profile":"2016 +30%",
|
||||
"units":"mmol",
|
||||
"enteredBy":"sony",
|
||||
"NSCLIENT_ID":1496294454309,
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* {
|
||||
* "_id":"592fa43ed97496a80da913d2",
|
||||
* "created_at":"2017-06-01T05:20:06Z",
|
||||
* "eventType":"Profile Switch",
|
||||
* "profile":"2016 +30%",
|
||||
* "units":"mmol",
|
||||
* "enteredBy":"sony",
|
||||
* "NSCLIENT_ID":1496294454309,
|
||||
* }
|
||||
*/
|
||||
|
||||
public void createProfileSwitchFromJsonIfNotExists(JSONObject trJson) {
|
||||
try {
|
||||
|
@ -1796,6 +1816,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
// ---------------- Insight history handling ---------------
|
||||
|
||||
public void createOrUpdate(InsightHistoryOffset offset) {
|
||||
|
@ -1806,6 +1827,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public InsightHistoryOffset getInsightHistoryOffset(String pumpSerial) {
|
||||
try {
|
||||
return getDaoInsightHistoryOffset().queryForId(pumpSerial);
|
||||
|
@ -1815,6 +1837,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void createOrUpdate(InsightBolusID bolusID) {
|
||||
try {
|
||||
getDaoInsightBolusID().createOrUpdate(bolusID);
|
||||
|
@ -1823,19 +1846,19 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public InsightBolusID getInsightBolusID(String pumpSerial, int bolusID, long timestamp) {
|
||||
try {
|
||||
return getDaoInsightBolusID().queryBuilder()
|
||||
.where().eq("pumpSerial", pumpSerial)
|
||||
.and().eq("bolusID", bolusID)
|
||||
.and().between("timestamp", timestamp - 259200000, timestamp + 259200000)
|
||||
.queryForFirst();
|
||||
return getDaoInsightBolusID().queryBuilder().where().eq("pumpSerial", pumpSerial).and()
|
||||
.eq("bolusID", bolusID).and().between("timestamp", timestamp - 259200000, timestamp + 259200000)
|
||||
.queryForFirst();
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void createOrUpdate(InsightPumpID pumpID) {
|
||||
try {
|
||||
getDaoInsightPumpID().createOrUpdate(pumpID);
|
||||
|
@ -1844,14 +1867,12 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public InsightPumpID getPumpStoppedEvent(String pumpSerial, long before) {
|
||||
try {
|
||||
return getDaoInsightPumpID().queryBuilder()
|
||||
.orderBy("timestamp", false)
|
||||
.where().eq("pumpSerial", pumpSerial)
|
||||
.and().in("eventType", "PumpStopped", "PumpPaused")
|
||||
.and().lt("timestamp", before)
|
||||
.queryForFirst();
|
||||
return getDaoInsightPumpID().queryBuilder().orderBy("timestamp", false).where()
|
||||
.eq("pumpSerial", pumpSerial).and().in("eventType", "PumpStopped", "PumpPaused").and()
|
||||
.lt("timestamp", before).queryForFirst();
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
|
|
|
@ -3,16 +3,16 @@ package info.nightscout.androidaps.interfaces;
|
|||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.data.Intervals;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileIntervals;
|
||||
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.plugins.treatments.Treatment;
|
||||
import info.nightscout.androidaps.data.Intervals;
|
||||
import info.nightscout.androidaps.data.ProfileIntervals;
|
||||
|
||||
/**
|
||||
* Created by mike on 14.06.2016.
|
||||
|
@ -20,47 +20,94 @@ import info.nightscout.androidaps.data.ProfileIntervals;
|
|||
public interface TreatmentsInterface {
|
||||
|
||||
void updateTotalIOBTreatments();
|
||||
|
||||
|
||||
void updateTotalIOBTempBasals();
|
||||
|
||||
|
||||
IobTotal getLastCalculationTreatments();
|
||||
|
||||
|
||||
IobTotal getCalculationToTimeTreatments(long time);
|
||||
|
||||
|
||||
IobTotal getLastCalculationTempBasals();
|
||||
|
||||
|
||||
IobTotal getCalculationToTimeTempBasals(long time, Profile profile);
|
||||
|
||||
|
||||
MealData getMealData();
|
||||
|
||||
|
||||
List<Treatment> getTreatmentsFromHistory();
|
||||
|
||||
|
||||
List<Treatment> getTreatments5MinBackFromHistory(long time);
|
||||
|
||||
|
||||
long getLastBolusTime();
|
||||
|
||||
|
||||
// real basals (not faked by extended bolus)
|
||||
boolean isInHistoryRealTempBasalInProgress();
|
||||
|
||||
|
||||
TemporaryBasal getRealTempBasalFromHistory(long time);
|
||||
|
||||
|
||||
boolean addToHistoryTempBasal(TemporaryBasal tempBasal);
|
||||
|
||||
|
||||
// basal that can be faked by extended boluses
|
||||
boolean isTempBasalInProgress();
|
||||
|
||||
|
||||
TemporaryBasal getTempBasalFromHistory(long time);
|
||||
|
||||
|
||||
Intervals<TemporaryBasal> getTemporaryBasalsFromHistory();
|
||||
|
||||
|
||||
boolean isInHistoryExtendedBoluslInProgress();
|
||||
|
||||
|
||||
ExtendedBolus getExtendedBolusFromHistory(long time);
|
||||
|
||||
|
||||
Intervals<ExtendedBolus> getExtendedBolusesFromHistory();
|
||||
|
||||
|
||||
boolean addToHistoryExtendedBolus(ExtendedBolus extendedBolus);
|
||||
|
||||
|
||||
boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo, boolean allowUpdate);
|
||||
|
||||
|
||||
TempTarget getTempTargetFromHistory();
|
||||
|
||||
|
||||
TempTarget getTempTargetFromHistory(long time);
|
||||
|
||||
|
||||
Intervals<TempTarget> getTempTargetsFromHistory();
|
||||
|
||||
|
||||
void addToHistoryTempTarget(TempTarget tempTarget);
|
||||
|
||||
|
||||
ProfileSwitch getProfileSwitchFromHistory(long time);
|
||||
|
||||
|
||||
ProfileIntervals<ProfileSwitch> getProfileSwitchesFromHistory();
|
||||
|
||||
|
||||
void addToHistoryProfileSwitch(ProfileSwitch profileSwitch);
|
||||
|
||||
|
||||
long oldestDataAvailable();
|
||||
|
||||
|
||||
List<Treatment> getTreatmentsFromHistoryXMinutesAgo(int minutesAgo);
|
||||
|
||||
}
|
||||
|
|
|
@ -1712,12 +1712,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
|
||||
|
||||
public int getBackgroundColor(OverviewColorScheme scheme) {
|
||||
return MainApp.gc(scheme.getBackground(isNewColor));
|
||||
return MainApp.gc(scheme.getBackground(useNewRibbonColors));
|
||||
}
|
||||
|
||||
|
||||
public int getTextColor(OverviewColorScheme scheme) {
|
||||
return MainApp.gc(scheme.getTextColor(isNewColor));
|
||||
return MainApp.gc(scheme.getTextColor(useNewRibbonColors));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.general.wear;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
|
@ -35,11 +36,14 @@ public class WearPlugin extends PluginBase {
|
|||
private final Context ctx;
|
||||
|
||||
private static WearPlugin wearPlugin;
|
||||
private static String TAG = "WearPlugin";
|
||||
|
||||
|
||||
public static WearPlugin getPlugin() {
|
||||
return wearPlugin;
|
||||
}
|
||||
|
||||
|
||||
public static WearPlugin initPlugin(Context ctx) {
|
||||
|
||||
if (wearPlugin == null) {
|
||||
|
@ -49,18 +53,15 @@ public class WearPlugin extends PluginBase {
|
|||
return wearPlugin;
|
||||
}
|
||||
|
||||
|
||||
WearPlugin(Context ctx) {
|
||||
super(new PluginDescription()
|
||||
.mainType(PluginType.GENERAL)
|
||||
.fragmentClass(WearFragment.class.getName())
|
||||
.pluginName(R.string.wear)
|
||||
.shortName(R.string.wear_shortname)
|
||||
.preferencesId(R.xml.pref_wear)
|
||||
.description(R.string.description_wear)
|
||||
);
|
||||
super(new PluginDescription().mainType(PluginType.GENERAL).fragmentClass(WearFragment.class.getName())
|
||||
.pluginName(R.string.wear).shortName(R.string.wear_shortname).preferencesId(R.xml.pref_wear)
|
||||
.description(R.string.description_wear));
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
MainApp.bus().register(this);
|
||||
|
@ -70,38 +71,53 @@ public class WearPlugin extends PluginBase {
|
|||
super.onStart();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
MainApp.bus().unregister(this);
|
||||
}
|
||||
|
||||
|
||||
private void sendDataToWatch(boolean status, boolean basals, boolean bgValue) {
|
||||
if (isEnabled(getType())) { //only start service when this plugin is enabled
|
||||
|
||||
//Log.d(TAG, "WR: WearPlugin:sendDataToWatch (status=" + status + ",basals=" + basals + ",bgValue=" + bgValue + ")");
|
||||
|
||||
if (isEnabled(getType())) { // only start service when this plugin is enabled
|
||||
|
||||
if (bgValue) {
|
||||
ctx.startService(new Intent(ctx, WatchUpdaterService.class));
|
||||
}
|
||||
|
||||
if (basals) {
|
||||
ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_BASALS));
|
||||
ctx.startService(new Intent(ctx, WatchUpdaterService.class)
|
||||
.setAction(WatchUpdaterService.ACTION_SEND_BASALS));
|
||||
}
|
||||
|
||||
if (status) {
|
||||
ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_STATUS));
|
||||
ctx.startService(new Intent(ctx, WatchUpdaterService.class)
|
||||
.setAction(WatchUpdaterService.ACTION_SEND_STATUS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void resendDataToWatch() {
|
||||
//Log.d(TAG, "WR: WearPlugin:resendDataToWatch");
|
||||
ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_RESEND));
|
||||
}
|
||||
|
||||
|
||||
void openSettings() {
|
||||
//Log.d(TAG, "WR: WearPlugin:openSettings");
|
||||
ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_OPEN_SETTINGS));
|
||||
}
|
||||
|
||||
|
||||
void requestNotificationCancel(String actionstring) {
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_CANCEL_NOTIFICATION);
|
||||
//Log.d(TAG, "WR: WearPlugin:requestNotificationCancel");
|
||||
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class)
|
||||
.setAction(WatchUpdaterService.ACTION_CANCEL_NOTIFICATION);
|
||||
intent.putExtra("actionstring", actionstring);
|
||||
ctx.startService(intent);
|
||||
}
|
||||
|
@ -115,36 +131,43 @@ public class WearPlugin extends PluginBase {
|
|||
sendDataToWatch(true, false, false);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventTreatmentChange ev) {
|
||||
sendDataToWatch(true, true, false);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventTempBasalChange ev) {
|
||||
sendDataToWatch(true, true, false);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventOpenAPSUpdateGui ev) {
|
||||
sendDataToWatch(true, true, false);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventExtendedBolusChange ev) {
|
||||
sendDataToWatch(true, true, false);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventNewBG ev) {
|
||||
sendDataToWatch(true, true, true);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventNewBasalProfile ev) {
|
||||
sendDataToWatch(false, true, false);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventRefreshOverview ev) {
|
||||
if (WatchUpdaterService.shouldReportLoopStatus(LoopPlugin.getPlugin().isEnabled(PluginType.LOOP))) {
|
||||
|
@ -156,26 +179,31 @@ public class WearPlugin extends PluginBase {
|
|||
@Subscribe
|
||||
public void onStatusEvent(final EventOverviewBolusProgress ev) {
|
||||
if (!ev.isSMB() || SP.getBoolean("wear_notifySMB", true)) {
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS);
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class)
|
||||
.setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS);
|
||||
intent.putExtra("progresspercent", ev.percent);
|
||||
intent.putExtra("progressstatus", ev.status);
|
||||
ctx.startService(intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventBolusRequested ev) {
|
||||
String status = String.format(MainApp.gs(R.string.bolusrequested), ev.getAmount());
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS);
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class)
|
||||
.setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS);
|
||||
intent.putExtra("progresspercent", 0);
|
||||
intent.putExtra("progressstatus", status);
|
||||
ctx.startService(intent);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventDismissBolusprogressIfRunning ev) {
|
||||
if (ev.result == null) return;
|
||||
if (ev.result == null)
|
||||
return;
|
||||
|
||||
String status;
|
||||
if (ev.result.success) {
|
||||
|
@ -183,34 +211,41 @@ public class WearPlugin extends PluginBase {
|
|||
} else {
|
||||
status = MainApp.gs(R.string.nosuccess);
|
||||
}
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS);
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class)
|
||||
.setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS);
|
||||
intent.putExtra("progresspercent", 100);
|
||||
intent.putExtra("progressstatus", status);
|
||||
ctx.startService(intent);
|
||||
}
|
||||
|
||||
|
||||
public void requestActionConfirmation(String title, String message, String actionstring) {
|
||||
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_ACTIONCONFIRMATIONREQUEST);
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class)
|
||||
.setAction(WatchUpdaterService.ACTION_SEND_ACTIONCONFIRMATIONREQUEST);
|
||||
intent.putExtra("title", title);
|
||||
intent.putExtra("message", message);
|
||||
intent.putExtra("actionstring", actionstring);
|
||||
ctx.startService(intent);
|
||||
}
|
||||
|
||||
|
||||
public void requestChangeConfirmation(String title, String message, String actionstring) {
|
||||
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_CHANGECONFIRMATIONREQUEST);
|
||||
Intent intent = new Intent(ctx, WatchUpdaterService.class)
|
||||
.setAction(WatchUpdaterService.ACTION_SEND_CHANGECONFIRMATIONREQUEST);
|
||||
intent.putExtra("title", title);
|
||||
intent.putExtra("message", message);
|
||||
intent.putExtra("actionstring", actionstring);
|
||||
ctx.startService(intent);
|
||||
}
|
||||
|
||||
|
||||
public static void registerWatchUpdaterService(WatchUpdaterService wus) {
|
||||
watchUS = wus;
|
||||
}
|
||||
|
||||
|
||||
public static void unRegisterWatchUpdaterService() {
|
||||
watchUS = null;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package info.nightscout.androidaps.plugins.general.wear.wearintegration;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -12,41 +15,126 @@ import com.google.android.gms.wearable.PutDataMapRequest;
|
|||
import com.google.android.gms.wearable.PutDataRequest;
|
||||
import com.google.android.gms.wearable.Wearable;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Created by emmablack on 12/26/14.
|
||||
*/
|
||||
class SendToDataLayerThread extends AsyncTask<DataMap,Void,Void> {
|
||||
class SendToDataLayerThread extends AsyncTask<DataMap, Void, Void> {
|
||||
|
||||
private GoogleApiClient googleApiClient;
|
||||
private static final String TAG = "SendDataThread";
|
||||
String path;
|
||||
private static final String TAG = "SendToDataLayerThread";
|
||||
private String path;
|
||||
private String logPrefix = ""; // "WR: ";
|
||||
private static int concurrency = 0;
|
||||
private static int state = 0;
|
||||
private static final ReentrantLock lock = new ReentrantLock();
|
||||
private static long lastlock = 0;
|
||||
private static final boolean testlockup = false; // always false in production
|
||||
|
||||
|
||||
SendToDataLayerThread(String path, GoogleApiClient pGoogleApiClient) {
|
||||
// Log.d(TAG, logPrefix + "SendToDataLayerThread: " + path);
|
||||
this.path = path;
|
||||
googleApiClient = pGoogleApiClient;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
concurrency++;
|
||||
if ((concurrency > 12) || ((concurrency > 3 && (lastlock != 0) && (tsl() - lastlock) > 300000))) {
|
||||
// error if 9 concurrent threads or lock held for >5 minutes with concurrency of 4
|
||||
final String err = "Wear Integration deadlock detected!! " + ((lastlock != 0) ? "locked" : "") + " state:"
|
||||
+ state + " @" + hourMinuteString(tsl());
|
||||
// Home.toaststaticnext(err);
|
||||
Log.e(TAG, logPrefix + err);
|
||||
}
|
||||
if (concurrency < 0)
|
||||
Log.d(TAG, logPrefix + "Wear Integration impossible concurrency!!");
|
||||
|
||||
Log.d(TAG, logPrefix + "SendDataToLayerThread pre-execute concurrency: " + concurrency);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(DataMap... params) {
|
||||
try {
|
||||
final NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(15, TimeUnit.SECONDS);
|
||||
for (Node node : nodes.getNodes()) {
|
||||
for (DataMap dataMap : params) {
|
||||
PutDataMapRequest putDMR = PutDataMapRequest.create(path);
|
||||
putDMR.getDataMap().putAll(dataMap);
|
||||
PutDataRequest request = putDMR.asPutDataRequest();
|
||||
DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleApiClient, request).await(15, TimeUnit.SECONDS);
|
||||
if (result.getStatus().isSuccess()) {
|
||||
Log.d(TAG, "DataMap: " + dataMap + " sent to: " + node.getDisplayName());
|
||||
} else {
|
||||
Log.d(TAG, "ERROR: failed to send DataMap");
|
||||
}
|
||||
}
|
||||
if (testlockup) {
|
||||
try {
|
||||
Log.e(TAG, logPrefix + "WARNING RUNNING TEST LOCK UP CODE - NEVER FOR PRODUCTION");
|
||||
Thread.sleep(1000000); // DEEEBBUUGGGG
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Got exception sending data to wear: " + e.toString());
|
||||
}
|
||||
sendToWear(params);
|
||||
concurrency--;
|
||||
Log.d(TAG, logPrefix + "SendDataToLayerThread post-execute concurrency: " + concurrency);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Debug function to expose where it might be locking up
|
||||
private synchronized void sendToWear(final DataMap... params) {
|
||||
if (!lock.tryLock()) {
|
||||
Log.d(TAG, logPrefix + "Concurrent access - waiting for thread unlock");
|
||||
lock.lock(); // enforce single threading
|
||||
Log.d(TAG, logPrefix + "Thread unlocked - proceeding");
|
||||
}
|
||||
lastlock = tsl();
|
||||
try {
|
||||
if (state != 0) {
|
||||
Log.e(TAG, logPrefix + "WEAR STATE ERROR: state=" + state);
|
||||
}
|
||||
state = 1;
|
||||
final NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(15,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
Log.d(TAG, logPrefix + "Nodes: " + nodes);
|
||||
|
||||
state = 2;
|
||||
for (Node node : nodes.getNodes()) {
|
||||
state = 3;
|
||||
for (DataMap dataMap : params) {
|
||||
state = 4;
|
||||
PutDataMapRequest putDMR = PutDataMapRequest.create(path);
|
||||
state = 5;
|
||||
putDMR.getDataMap().putAll(dataMap);
|
||||
putDMR.setUrgent();
|
||||
state = 6;
|
||||
PutDataRequest request = putDMR.asPutDataRequest();
|
||||
state = 7;
|
||||
DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleApiClient, request).await(15,
|
||||
TimeUnit.SECONDS);
|
||||
state = 8;
|
||||
if (result.getStatus().isSuccess()) {
|
||||
Log.d(TAG, logPrefix + "DataMap: " + dataMap + " sent to: " + node.getDisplayName());
|
||||
} else {
|
||||
Log.e(TAG, logPrefix + "ERROR: failed to send DataMap");
|
||||
result = Wearable.DataApi.putDataItem(googleApiClient, request).await(30, TimeUnit.SECONDS);
|
||||
if (result.getStatus().isSuccess()) {
|
||||
Log.d(TAG, logPrefix + "DataMap retry: " + dataMap + " sent to: " + node.getDisplayName());
|
||||
} else {
|
||||
Log.e(TAG, logPrefix + "ERROR on retry: failed to send DataMap: "
|
||||
+ result.getStatus().toString());
|
||||
}
|
||||
}
|
||||
state = 9;
|
||||
}
|
||||
}
|
||||
state = 0;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, logPrefix + "Got exception in sendToWear: " + e.toString());
|
||||
} finally {
|
||||
lastlock = 0;
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static long tsl() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
private static String hourMinuteString(long timestamp) {
|
||||
return android.text.format.DateFormat.format("kk:mm", timestamp).toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
package info.nightscout.androidaps.plugins.general.wear.wearintegration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
|
@ -14,19 +22,16 @@ import android.util.Log;
|
|||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.wearable.CapabilityApi;
|
||||
import com.google.android.gms.wearable.CapabilityInfo;
|
||||
import com.google.android.gms.wearable.DataMap;
|
||||
import com.google.android.gms.wearable.MessageEvent;
|
||||
import com.google.android.gms.wearable.Node;
|
||||
import com.google.android.gms.wearable.PutDataMapRequest;
|
||||
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;
|
||||
|
@ -37,36 +42,42 @@ 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.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
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;
|
||||
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;
|
||||
import info.nightscout.androidaps.utils.ToastUtils;
|
||||
|
||||
public class WatchUpdaterService extends WearableListenerService implements
|
||||
GoogleApiClient.ConnectionCallbacks,
|
||||
GoogleApiClient.OnConnectionFailedListener {
|
||||
public class WatchUpdaterService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(WatchUpdaterService.class);
|
||||
private static final String TAG = "WatchUpdaterService";
|
||||
|
||||
// ACTIONS
|
||||
public static final String ACTION_RESEND = WatchUpdaterService.class.getName().concat(".Resend");
|
||||
public static final String ACTION_OPEN_SETTINGS = WatchUpdaterService.class.getName().concat(".OpenSettings");
|
||||
public static final String ACTION_SEND_STATUS = WatchUpdaterService.class.getName().concat(".SendStatus");
|
||||
public static final String ACTION_SEND_BASALS = WatchUpdaterService.class.getName().concat(".SendBasals");
|
||||
public static final String ACTION_SEND_BOLUSPROGRESS = WatchUpdaterService.class.getName().concat(".BolusProgress");
|
||||
public static final String ACTION_SEND_ACTIONCONFIRMATIONREQUEST = WatchUpdaterService.class.getName().concat(".ActionConfirmationRequest");
|
||||
public static final String ACTION_SEND_CHANGECONFIRMATIONREQUEST = WatchUpdaterService.class.getName().concat(".ChangeConfirmationRequest");
|
||||
public static final String ACTION_CANCEL_NOTIFICATION = WatchUpdaterService.class.getName().concat(".CancelNotification");
|
||||
public static final String ACTION_SEND_ACTIONCONFIRMATIONREQUEST = WatchUpdaterService.class.getName().concat(
|
||||
".ActionConfirmationRequest");
|
||||
public static final String ACTION_SEND_CHANGECONFIRMATIONREQUEST = WatchUpdaterService.class.getName().concat(
|
||||
".ChangeConfirmationRequest");
|
||||
public static final String ACTION_CANCEL_NOTIFICATION = WatchUpdaterService.class.getName().concat(
|
||||
".CancelNotification");
|
||||
|
||||
private GoogleApiClient googleApiClient;
|
||||
// PATHS
|
||||
public static final String WEARABLE_DATA_PATH = "/nightscout_watch_data";
|
||||
public static final String WEARABLE_RESEND_PATH = "/nightscout_watch_data_resend";
|
||||
private static final String WEARABLE_CANCELBOLUS_PATH = "/nightscout_watch_cancel_bolus";
|
||||
|
@ -81,16 +92,25 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
public static final String ACTION_CONFIRMATION_REQUEST_PATH = "/nightscout_watch_actionconfirmationrequest";
|
||||
public static final String ACTION_CHANGECONFIRMATION_REQUEST_PATH = "/nightscout_watch_changeconfirmationrequest";
|
||||
public static final String ACTION_CANCELNOTIFICATION_REQUEST_PATH = "/nightscout_watch_cancelnotificationrequest";
|
||||
// Phone - Capabilites
|
||||
private static final String CAPABILITY_PHONE_APP = "phone_app_sync_bgs";
|
||||
private static final String MESSAGE_PATH_PHONE = "/phone_message_path";
|
||||
// Wear - Capabilites
|
||||
private static final String CAPABILITY_WEAR_APP = "wear_app_sync_bgs";
|
||||
private static final String MESSAGE_PATH_WEAR = "/wear_message_path";
|
||||
|
||||
|
||||
private GoogleApiClient googleApiClient;
|
||||
boolean wear_integration = false;
|
||||
SharedPreferences mPrefs;
|
||||
private static boolean lastLoopStatus;
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(WatchUpdaterService.class);
|
||||
|
||||
private Handler handler;
|
||||
|
||||
private String mWearNodeId = null;
|
||||
private String localnode = null;
|
||||
private String logPrefix = ""; // "WR: "
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||
|
@ -106,38 +126,43 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void listenForChangeInSettings() {
|
||||
WearPlugin.registerWatchUpdaterService(this);
|
||||
}
|
||||
|
||||
|
||||
public void setSettings() {
|
||||
wear_integration = WearPlugin.getPlugin().isEnabled(PluginType.GENERAL);
|
||||
// Log.d(TAG, "WR: wear_integration=" + wear_integration);
|
||||
if (wear_integration) {
|
||||
googleApiConnect();
|
||||
}
|
||||
}
|
||||
|
||||
public void googleApiConnect() {
|
||||
|
||||
private void googleApiConnect() {
|
||||
if (googleApiClient != null && (googleApiClient.isConnected() || googleApiClient.isConnecting())) {
|
||||
googleApiClient.disconnect();
|
||||
}
|
||||
googleApiClient = new GoogleApiClient.Builder(this)
|
||||
.addConnectionCallbacks(this)
|
||||
.addOnConnectionFailedListener(this)
|
||||
.addApi(Wearable.API)
|
||||
.build();
|
||||
googleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
|
||||
.addOnConnectionFailedListener(this).addApi(Wearable.API).build();
|
||||
Wearable.MessageApi.addListener(googleApiClient, this);
|
||||
if (googleApiClient.isConnected()) {
|
||||
Log.d("WatchUpdater", "API client is connected");
|
||||
Log.d(TAG, logPrefix + "API client is connected");
|
||||
} else {
|
||||
// Log.d("WatchUpdater", logPrefix + "API client is not connected and is trying to connect");
|
||||
googleApiClient.connect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
String action = intent != null ? intent.getAction() : null;
|
||||
|
||||
// Log.d(TAG, logPrefix + "onStartCommand: " + action);
|
||||
|
||||
if (wear_integration) {
|
||||
handler.post(() -> {
|
||||
if (googleApiClient.isConnected()) {
|
||||
|
@ -150,7 +175,8 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
} else if (ACTION_SEND_BASALS.equals(action)) {
|
||||
sendBasals();
|
||||
} else if (ACTION_SEND_BOLUSPROGRESS.equals(action)) {
|
||||
sendBolusProgress(intent.getIntExtra("progresspercent", 0), intent.hasExtra("progressstatus") ? intent.getStringExtra("progressstatus") : "");
|
||||
sendBolusProgress(intent.getIntExtra("progresspercent", 0),
|
||||
intent.hasExtra("progressstatus") ? intent.getStringExtra("progressstatus") : "");
|
||||
} else if (ACTION_SEND_ACTIONCONFIRMATIONREQUEST.equals(action)) {
|
||||
String title = intent.getStringExtra("title");
|
||||
String message = intent.getStringExtra("message");
|
||||
|
@ -177,13 +203,63 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
}
|
||||
|
||||
|
||||
private void updateWearSyncBgsCapability(CapabilityInfo capabilityInfo) {
|
||||
Log.d("WatchUpdaterService", logPrefix + "CabilityInfo: " + capabilityInfo);
|
||||
Set<Node> connectedNodes = capabilityInfo.getNodes();
|
||||
mWearNodeId = pickBestNodeId(connectedNodes);
|
||||
}
|
||||
|
||||
|
||||
private String pickBestNodeId(Set<Node> nodes) {
|
||||
String bestNodeId = null;
|
||||
// Find a nearby node or pick one arbitrarily
|
||||
for (Node node : nodes) {
|
||||
if (node.isNearby()) {
|
||||
return node.getId();
|
||||
}
|
||||
bestNodeId = node.getId();
|
||||
}
|
||||
return bestNodeId;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onConnected(Bundle connectionHint) {
|
||||
CapabilityApi.CapabilityListener capabilityListener = capabilityInfo -> {
|
||||
updateWearSyncBgsCapability(capabilityInfo);
|
||||
// Log.d(TAG, logPrefix + "onConnected onCapabilityChanged mWearNodeID:" + mWearNodeId);
|
||||
// new CheckWearableConnected().execute();
|
||||
};
|
||||
|
||||
Wearable.CapabilityApi.addCapabilityListener(googleApiClient, capabilityListener, CAPABILITY_WEAR_APP);
|
||||
sendData();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPeerConnected(com.google.android.gms.wearable.Node peer) {// KS
|
||||
super.onPeerConnected(peer);
|
||||
String id = peer.getId();
|
||||
String name = peer.getDisplayName();
|
||||
// Log.d(TAG, logPrefix + "onPeerConnected peer name & ID: " + name + "|" + id);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPeerDisconnected(com.google.android.gms.wearable.Node peer) {// KS
|
||||
super.onPeerDisconnected(peer);
|
||||
String id = peer.getId();
|
||||
String name = peer.getDisplayName();
|
||||
// Log.d(TAG, logPrefix + "onPeerDisconnected peer name & ID: " + name + "|" + id);
|
||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMessageReceived(MessageEvent event) {
|
||||
|
||||
// Log.d(TAG, logPrefix + "onMessageRecieved: " + event);
|
||||
|
||||
if (wear_integration) {
|
||||
if (event != null && event.getPath().equals(WEARABLE_RESEND_PATH)) {
|
||||
resendData();
|
||||
|
@ -207,13 +283,16 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void cancelBolus() {
|
||||
ConfigBuilderPlugin.getPlugin().getActivePump().stopBolusDelivering();
|
||||
}
|
||||
|
||||
|
||||
private void sendData() {
|
||||
|
||||
BgReading lastBG = DatabaseHelper.lastBg();
|
||||
// Log.d(TAG, logPrefix + "LastBg=" + lastBG);
|
||||
if (lastBG != null) {
|
||||
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
|
||||
|
||||
|
@ -228,18 +307,19 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
return;
|
||||
}
|
||||
|
||||
new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient).execute(dataMap);
|
||||
executeTask(new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient), dataMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private DataMap dataMapSingleBG(BgReading lastBG, GlucoseStatus glucoseStatus) {
|
||||
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||
|
||||
Double lowLine = SafeParse.stringToDouble(mPrefs.getString("low_mark", "0"));
|
||||
Double highLine = SafeParse.stringToDouble(mPrefs.getString("high_mark", "0"));
|
||||
|
||||
//convert to mg/dl
|
||||
// convert to mg/dl
|
||||
if (!units.equals(Constants.MGDL)) {
|
||||
lowLine *= Constants.MMOLL_TO_MGDL;
|
||||
highLine *= Constants.MMOLL_TO_MGDL;
|
||||
|
@ -271,8 +351,10 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
dataMap.putString("avgDelta", "--");
|
||||
} else {
|
||||
dataMap.putString("slopeArrow", slopeArrow(glucoseStatus.delta));
|
||||
dataMap.putString("delta", deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units));
|
||||
dataMap.putString("avgDelta", deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units));
|
||||
dataMap.putString("delta",
|
||||
deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units));
|
||||
dataMap.putString("avgDelta",
|
||||
deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units));
|
||||
}
|
||||
dataMap.putLong("sgvLevel", sgvLevel);
|
||||
dataMap.putDouble("sgvDouble", lastBG.value);
|
||||
|
@ -281,13 +363,13 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
return dataMap;
|
||||
}
|
||||
|
||||
|
||||
private String deltastring(double deltaMGDL, double deltaMMOL, String units) {
|
||||
String deltastring = "";
|
||||
if (deltaMGDL >= 0) {
|
||||
deltastring += "+";
|
||||
} else {
|
||||
deltastring += "-";
|
||||
|
||||
}
|
||||
|
||||
boolean detailed = SP.getBoolean("wear_detailed_delta", false);
|
||||
|
@ -307,6 +389,7 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
return deltastring;
|
||||
}
|
||||
|
||||
|
||||
private String slopeArrow(double delta) {
|
||||
if (delta <= (-3.5 * 5)) {
|
||||
return "\u21ca";
|
||||
|
@ -330,10 +413,11 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
if (googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) {
|
||||
googleApiConnect();
|
||||
}
|
||||
long startTime = System.currentTimeMillis() - (long) (60000 * 60 * 5.5);
|
||||
long startTime = System.currentTimeMillis() - (long)(60000 * 60 * 5.5);
|
||||
BgReading last_bg = DatabaseHelper.lastBg();
|
||||
|
||||
if (last_bg == null) return;
|
||||
if (last_bg == null)
|
||||
return;
|
||||
|
||||
List<BgReading> graph_bgs = MainApp.getDbHelper().getBgreadingsDataFromTime(startTime, true);
|
||||
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(true);
|
||||
|
@ -352,28 +436,29 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
}
|
||||
}
|
||||
entries.putDataMapArrayList("entries", dataMaps);
|
||||
new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient).execute(entries);
|
||||
executeTask(new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient), entries);
|
||||
|
||||
// Wearable.DataApi.putDataItem(googleApiClient, putDataRequest);
|
||||
}
|
||||
sendPreferences();
|
||||
sendPreferences(); // DMR
|
||||
sendBasals();
|
||||
sendStatus();
|
||||
sendStatus(); // DMR
|
||||
}
|
||||
|
||||
|
||||
private void sendBasals() {
|
||||
if (googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) {
|
||||
googleApiConnect();
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
final long startTimeWindow = now - (long) (60000 * 60 * 5.5);
|
||||
|
||||
final long startTimeWindow = now - (long)(60000 * 60 * 5.5);
|
||||
|
||||
ArrayList<DataMap> basals = new ArrayList<>();
|
||||
ArrayList<DataMap> temps = new ArrayList<>();
|
||||
ArrayList<DataMap> boluses = new ArrayList<>();
|
||||
ArrayList<DataMap> predictions = new ArrayList<>();
|
||||
|
||||
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
|
||||
if (profile == null) {
|
||||
|
@ -401,33 +486,32 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
for (; runningTime < now; runningTime += 5 * 60 * 1000) {
|
||||
Profile profileTB = ProfileFunctions.getInstance().getProfile(runningTime);
|
||||
//basal rate
|
||||
// basal rate
|
||||
endBasalValue = profile.getBasal(runningTime);
|
||||
if (endBasalValue != beginBasalValue) {
|
||||
//push the segment we recently left
|
||||
// push the segment we recently left
|
||||
basals.add(basalMap(beginBasalSegmentTime, runningTime, beginBasalValue));
|
||||
|
||||
//begin new Basal segment
|
||||
// begin new Basal segment
|
||||
beginBasalSegmentTime = runningTime;
|
||||
beginBasalValue = endBasalValue;
|
||||
}
|
||||
|
||||
//temps
|
||||
// temps
|
||||
tb2 = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(runningTime);
|
||||
|
||||
if (tb1 == null && tb2 == null) {
|
||||
//no temp stays no temp
|
||||
// no temp stays no temp
|
||||
|
||||
} else if (tb1 != null && tb2 == null) {
|
||||
//temp is over -> push it
|
||||
// temp is over -> push it
|
||||
temps.add(tempDatamap(tb_start, tb_before, runningTime, endBasalValue, tb_amount));
|
||||
tb1 = null;
|
||||
|
||||
} else if (tb1 == null && tb2 != null) {
|
||||
//temp begins
|
||||
// temp begins
|
||||
tb1 = tb2;
|
||||
tb_start = runningTime;
|
||||
tb_before = endBasalValue;
|
||||
|
@ -445,16 +529,16 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
}
|
||||
}
|
||||
if (beginBasalSegmentTime != runningTime) {
|
||||
//push the remaining segment
|
||||
// push the remaining segment
|
||||
basals.add(basalMap(beginBasalSegmentTime, runningTime, beginBasalValue));
|
||||
}
|
||||
if (tb1 != null) {
|
||||
tb2 = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); //use "now" to express current situation
|
||||
tb2 = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); // use "now" to express current situation
|
||||
if (tb2 == null) {
|
||||
//express the cancelled temp by painting it down one minute early
|
||||
// express the cancelled temp by painting it down one minute early
|
||||
temps.add(tempDatamap(tb_start, tb_before, now - 1 * 60 * 1000, endBasalValue, tb_amount));
|
||||
} else {
|
||||
//express currently running temp by painting it a bit into the future
|
||||
// express currently running temp by painting it a bit into the future
|
||||
Profile profileNow = ProfileFunctions.getInstance().getProfile(now);
|
||||
double currentAmount = tb2.tempBasalConvertedToAbsolute(now, profileNow);
|
||||
if (currentAmount != tb_amount) {
|
||||
|
@ -465,45 +549,49 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
}
|
||||
}
|
||||
} else {
|
||||
tb2 = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); //use "now" to express current situation
|
||||
tb2 = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); // use "now" to express current situation
|
||||
if (tb2 != null) {
|
||||
//onset at the end
|
||||
// onset at the end
|
||||
Profile profileTB = ProfileFunctions.getInstance().getProfile(runningTime);
|
||||
double currentAmount = tb2.tempBasalConvertedToAbsolute(runningTime, profileTB);
|
||||
temps.add(tempDatamap(now - 1 * 60 * 1000, endBasalValue, runningTime + 5 * 60 * 1000, currentAmount, currentAmount));
|
||||
temps.add(tempDatamap(now - 1 * 60 * 1000, endBasalValue, runningTime + 5 * 60 * 1000, currentAmount,
|
||||
currentAmount));
|
||||
}
|
||||
}
|
||||
|
||||
List<Treatment> treatments = TreatmentsPlugin.getPlugin().getTreatmentsFromHistory();
|
||||
for (Treatment treatment : treatments) {
|
||||
if (treatment.date > startTimeWindow) {
|
||||
boluses.add(treatmentMap(treatment.date, treatment.insulin, treatment.carbs, treatment.isSMB, treatment.isValid));
|
||||
boluses.add(treatmentMap(treatment.date, treatment.insulin, treatment.carbs, treatment.isSMB,
|
||||
treatment.isValid));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
|
||||
if (SP.getBoolean("wear_predictions", true) && finalLastRun != null && finalLastRun.request.hasPredictions && finalLastRun.constraintsProcessed != null) {
|
||||
if (SP.getBoolean("wear_predictions", true) && finalLastRun != null && finalLastRun.request.hasPredictions
|
||||
&& finalLastRun.constraintsProcessed != null) {
|
||||
List<BgReading> predArray = finalLastRun.constraintsProcessed.getPredictions();
|
||||
|
||||
if (!predArray.isEmpty()) {
|
||||
for (BgReading bg : predArray) {
|
||||
if (bg.value < 40) continue;
|
||||
if (bg.value < 40)
|
||||
continue;
|
||||
predictions.add(predictionMap(bg.date, bg.value, bg.getPredectionColor()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DataMap dm = new DataMap();
|
||||
dm.putDataMapArrayList("basals", basals);
|
||||
dm.putDataMapArrayList("temps", temps);
|
||||
dm.putDataMapArrayList("boluses", boluses);
|
||||
dm.putDataMapArrayList("predictions", predictions);
|
||||
|
||||
new SendToDataLayerThread(BASAL_DATA_PATH, googleApiClient).execute(dm);
|
||||
executeTask(new SendToDataLayerThread(BASAL_DATA_PATH, googleApiClient), dm);
|
||||
}
|
||||
|
||||
|
||||
private DataMap tempDatamap(long startTime, double startBasal, long to, double toBasal, double amount) {
|
||||
DataMap dm = new DataMap();
|
||||
dm.putLong("starttime", startTime);
|
||||
|
@ -514,6 +602,7 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
return dm;
|
||||
}
|
||||
|
||||
|
||||
private DataMap basalMap(long startTime, long endTime, double amount) {
|
||||
DataMap dm = new DataMap();
|
||||
dm.putLong("starttime", startTime);
|
||||
|
@ -522,6 +611,7 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
return dm;
|
||||
}
|
||||
|
||||
|
||||
private DataMap treatmentMap(long date, double bolus, double carbs, boolean isSMB, boolean isValid) {
|
||||
DataMap dm = new DataMap();
|
||||
dm.putLong("date", date);
|
||||
|
@ -532,6 +622,7 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
return dm;
|
||||
}
|
||||
|
||||
|
||||
private DataMap predictionMap(long timestamp, double sgv, int color) {
|
||||
DataMap dm = new DataMap();
|
||||
dm.putLong("timestamp", timestamp);
|
||||
|
@ -544,35 +635,39 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
private void sendNotification() {
|
||||
if (googleApiClient.isConnected()) {
|
||||
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(OPEN_SETTINGS_PATH);
|
||||
//unique content
|
||||
// unique content
|
||||
dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
|
||||
dataMapRequest.getDataMap().putString("openSettings", "openSettings");
|
||||
PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest();
|
||||
debugData("sendNotification", putDataRequest);
|
||||
Wearable.DataApi.putDataItem(googleApiClient, putDataRequest);
|
||||
} else {
|
||||
Log.e("OpenSettings", "No connection to wearable available!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void sendBolusProgress(int progresspercent, String status) {
|
||||
if (googleApiClient.isConnected()) {
|
||||
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(BOLUS_PROGRESS_PATH);
|
||||
//unique content
|
||||
// unique content
|
||||
dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
|
||||
dataMapRequest.getDataMap().putString("bolusProgress", "bolusProgress");
|
||||
dataMapRequest.getDataMap().putString("progressstatus", status);
|
||||
dataMapRequest.getDataMap().putInt("progresspercent", progresspercent);
|
||||
PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest();
|
||||
debugData("sendBolusProgress", putDataRequest);
|
||||
Wearable.DataApi.putDataItem(googleApiClient, putDataRequest);
|
||||
} else {
|
||||
Log.e("BolusProgress", "No connection to wearable available!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void sendActionConfirmationRequest(String title, String message, String actionstring) {
|
||||
if (googleApiClient.isConnected()) {
|
||||
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(ACTION_CONFIRMATION_REQUEST_PATH);
|
||||
//unique content
|
||||
// unique content
|
||||
dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
|
||||
dataMapRequest.getDataMap().putString("actionConfirmationRequest", "actionConfirmationRequest");
|
||||
dataMapRequest.getDataMap().putString("title", title);
|
||||
|
@ -582,16 +677,18 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
log.debug("Requesting confirmation from wear: " + actionstring);
|
||||
|
||||
PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest();
|
||||
debugData("sendActionConfirmationRequest", putDataRequest);
|
||||
Wearable.DataApi.putDataItem(googleApiClient, putDataRequest);
|
||||
} else {
|
||||
Log.e("confirmationRequest", "No connection to wearable available!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void sendChangeConfirmationRequest(String title, String message, String actionstring) {
|
||||
if (googleApiClient.isConnected()) {
|
||||
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(ACTION_CHANGECONFIRMATION_REQUEST_PATH);
|
||||
//unique content
|
||||
// unique content
|
||||
dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
|
||||
dataMapRequest.getDataMap().putString("changeConfirmationRequest", "changeConfirmationRequest");
|
||||
dataMapRequest.getDataMap().putString("title", title);
|
||||
|
@ -601,16 +698,18 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
log.debug("Requesting confirmation from wear: " + actionstring);
|
||||
|
||||
PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest();
|
||||
debugData("sendChangeConfirmationRequest", putDataRequest);
|
||||
Wearable.DataApi.putDataItem(googleApiClient, putDataRequest);
|
||||
} else {
|
||||
Log.e("changeConfirmRequest", "No connection to wearable available!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void sendCancelNotificationRequest(String actionstring) {
|
||||
if (googleApiClient.isConnected()) {
|
||||
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(ACTION_CANCELNOTIFICATION_REQUEST_PATH);
|
||||
//unique content
|
||||
// unique content
|
||||
dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
|
||||
dataMapRequest.getDataMap().putString("cancelNotificationRequest", "cancelNotificationRequest");
|
||||
dataMapRequest.getDataMap().putString("actionstring", actionstring);
|
||||
|
@ -618,12 +717,14 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
log.debug("Canceling notification on wear: " + actionstring);
|
||||
|
||||
PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest();
|
||||
debugData("sendCancelNotificationRequest", putDataRequest);
|
||||
Wearable.DataApi.putDataItem(googleApiClient, putDataRequest);
|
||||
} else {
|
||||
Log.e("cancelNotificationRequest", "No connection to wearable available!");
|
||||
Log.e("cancelNotificationReq", "No connection to wearable available!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void sendStatus() {
|
||||
|
||||
if (googleApiClient.isConnected()) {
|
||||
|
@ -639,12 +740,13 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
IobTotal basalIob = treatmentsInterface.getLastCalculationTempBasals().round();
|
||||
|
||||
iobSum = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob);
|
||||
iobDetail = "(" + DecimalFormatter.to2Decimal(bolusIob.iob) + "|" + DecimalFormatter.to2Decimal(basalIob.basaliob) + ")";
|
||||
cobString = IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "WatcherUpdaterService").generateCOBString();
|
||||
iobDetail = "(" + DecimalFormatter.to2Decimal(bolusIob.iob) + "|"
|
||||
+ DecimalFormatter.to2Decimal(basalIob.basaliob) + ")";
|
||||
cobString = IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "WatcherUpdaterService")
|
||||
.generateCOBString();
|
||||
currentBasal = generateBasalString(treatmentsInterface);
|
||||
|
||||
//bgi
|
||||
|
||||
// bgi
|
||||
|
||||
double bgi = -(bolusIob.activity + basalIob.activity) * 5 * profile.getIsf();
|
||||
bgiString = "" + ((bgi >= 0) ? "+" : "") + DecimalFormatter.to1Decimal(bgi);
|
||||
|
@ -652,24 +754,23 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
status = generateStatusString(profile, currentBasal, iobSum, iobDetail, bgiString);
|
||||
}
|
||||
|
||||
|
||||
//batteries
|
||||
// batteries
|
||||
int phoneBattery = getBatteryLevel(getApplicationContext());
|
||||
String rigBattery = NSDeviceStatus.getInstance().getUploaderStatus().trim();
|
||||
|
||||
|
||||
long openApsStatus = -1;
|
||||
//OpenAPS status
|
||||
// OpenAPS status
|
||||
if (Config.APS) {
|
||||
//we are AndroidAPS
|
||||
openApsStatus = LoopPlugin.lastRun != null && LoopPlugin.lastRun.lastEnact != null && LoopPlugin.lastRun.lastEnact.getTime() != 0 ? LoopPlugin.lastRun.lastEnact.getTime() : -1;
|
||||
// we are AndroidAPS
|
||||
openApsStatus = LoopPlugin.lastRun != null && LoopPlugin.lastRun.lastEnact != null
|
||||
&& LoopPlugin.lastRun.lastEnact.getTime() != 0 ? LoopPlugin.lastRun.lastEnact.getTime() : -1;
|
||||
} else {
|
||||
//NSClient or remote
|
||||
// NSClient or remote
|
||||
openApsStatus = NSDeviceStatus.getOpenApsTimestamp();
|
||||
}
|
||||
|
||||
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(NEW_STATUS_PATH);
|
||||
//unique content
|
||||
// unique content
|
||||
dataMapRequest.getDataMap().putString("externalStatusString", status);
|
||||
dataMapRequest.getDataMap().putString("iobSum", iobSum);
|
||||
dataMapRequest.getDataMap().putString("iobDetail", iobDetail);
|
||||
|
@ -683,30 +784,50 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
dataMapRequest.getDataMap().putBoolean("showBgi", mPrefs.getBoolean("wear_showbgi", false));
|
||||
dataMapRequest.getDataMap().putInt("batteryLevel", (phoneBattery >= 30) ? 1 : 0);
|
||||
PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest();
|
||||
debugData("sendStatus", putDataRequest);
|
||||
Wearable.DataApi.putDataItem(googleApiClient, putDataRequest);
|
||||
} else {
|
||||
Log.e("SendStatus", "No connection to wearable available!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void sendPreferences() {
|
||||
if (googleApiClient.isConnected()) {
|
||||
|
||||
boolean wearcontrol = SP.getBoolean("wearcontrol", false);
|
||||
|
||||
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(NEW_PREFERENCES_PATH);
|
||||
//unique content
|
||||
// unique content
|
||||
dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
|
||||
dataMapRequest.getDataMap().putBoolean("wearcontrol", wearcontrol);
|
||||
PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest();
|
||||
debugData("sendPreferences", putDataRequest);
|
||||
Wearable.DataApi.putDataItem(googleApiClient, putDataRequest);
|
||||
} else {
|
||||
Log.e("SendStatus", "No connection to wearable available!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void debugData(String source, Object data) {
|
||||
// Log.d(TAG, "WR: " + source + " " + data);
|
||||
}
|
||||
|
||||
|
||||
private void executeTask(AsyncTask task, DataMap... parameters) {
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])parameters);
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
// task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
// } else {
|
||||
// task.execute();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
private String generateStatusString(Profile profile, String currentBasal, String iobSum, String iobDetail, String bgiString) {
|
||||
private String generateStatusString(Profile profile, String currentBasal, String iobSum, String iobDetail,
|
||||
String bgiString) {
|
||||
|
||||
String status = "";
|
||||
|
||||
|
@ -733,7 +854,7 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
|
||||
status += currentBasal + " " + iobString;
|
||||
|
||||
//add BGI if shown, otherwise return
|
||||
// add BGI if shown, otherwise return
|
||||
if (mPrefs.getBoolean("wear_showbgi", false)) {
|
||||
status += " " + bgiString;
|
||||
}
|
||||
|
@ -741,6 +862,7 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
return status;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
private String generateBasalString(TreatmentsInterface treatmentsInterface) {
|
||||
|
||||
|
@ -763,6 +885,7 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
return basalStringResult;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (googleApiClient != null && googleApiClient.isConnected()) {
|
||||
|
@ -771,18 +894,22 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
WearPlugin.unRegisterWatchUpdaterService();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onConnectionSuspended(int cause) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed(ConnectionResult connectionResult) {
|
||||
}
|
||||
|
||||
|
||||
public static boolean shouldReportLoopStatus(boolean enabled) {
|
||||
return (lastLoopStatus != enabled);
|
||||
}
|
||||
|
||||
|
||||
public static int getBatteryLevel(Context context) {
|
||||
Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
if (batteryIntent != null) {
|
||||
|
@ -791,7 +918,7 @@ public class WatchUpdaterService extends WearableListenerService implements
|
|||
if (level == -1 || scale == -1) {
|
||||
return 50;
|
||||
}
|
||||
return (int) (((float) level / (float) scale) * 100.0f);
|
||||
return (int)(((float)level / (float)scale) * 100.0f);
|
||||
}
|
||||
return 50;
|
||||
}
|
||||
|
|
|
@ -198,6 +198,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
}
|
||||
|
||||
|
||||
// TODO remove
|
||||
private void migrateSettings() {
|
||||
|
||||
if ("US (916 MHz)".equals(SP.getString(MedtronicConst.Prefs.PumpFrequency, null))) {
|
||||
|
@ -457,6 +458,10 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
this.pumpState = PumpDriverState.Connected;
|
||||
|
||||
// time (1h)
|
||||
medtronicUIComm.executeCommand(MedtronicCommandType.RealTimeClock);
|
||||
scheduleNextRefresh(MedtronicStatusRefreshType.PumpTime, 30);
|
||||
|
||||
readPumpHistory();
|
||||
|
||||
// TODO rewrite reading of data to be done in background or different thread perhaps ??
|
||||
|
@ -472,10 +477,6 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
// configuration (once and then if history shows config changes)
|
||||
medtronicUIComm.executeCommand(MedtronicCommandType.getSettings(MedtronicUtil.getMedtronicPumpModel()));
|
||||
|
||||
// time (1h)
|
||||
medtronicUIComm.executeCommand(MedtronicCommandType.RealTimeClock);
|
||||
scheduleNextRefresh(MedtronicStatusRefreshType.PumpTime, 30);
|
||||
|
||||
// read profile (once, later its controlled by isThisProfileSet method)
|
||||
medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD);
|
||||
|
||||
|
@ -511,86 +512,12 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
@Override
|
||||
public boolean isThisProfileSet(Profile profile) {
|
||||
return isThisProfileSet_New(profile);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public boolean isThisProfileSet_Old(Profile profile) {
|
||||
|
||||
if (!this.isInitialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// LOG.info("isThisProfileSet: check");
|
||||
|
||||
LOG.info("isThisProfileSet: check [basalProfileChanged={}, basalByHourSet={}, isBasalProfileInvalid={}",
|
||||
basalProfileChanged, getMDTPumpStatus().basalsByHour != null, isBasalProfileInvalid);
|
||||
|
||||
if (!basalProfileChanged && getMDTPumpStatus().basalsByHour != null && !isBasalProfileInvalid) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("isThisProfileSet: profile has not changed and is not invalid.");
|
||||
|
||||
return isProfileSame(profile);
|
||||
}
|
||||
|
||||
setRefreshButtonEnabled(false);
|
||||
|
||||
if (isPumpNotReachable()) {
|
||||
MedtronicUtil.sendNotification(MedtronicNotificationType.PumpUnreachable);
|
||||
setRefreshButtonEnabled(true);
|
||||
|
||||
return true; // we don't won't setting profile if pump unreachable
|
||||
}
|
||||
|
||||
MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable);
|
||||
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("isThisProfileSet: profile possible changed, reading from Pump.");
|
||||
|
||||
MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD);
|
||||
|
||||
boolean valid = false;
|
||||
boolean noData = false;
|
||||
|
||||
LOG.debug("isThisProfileSet: haveData={}", responseTask.hasData());
|
||||
|
||||
if (responseTask.hasData()) {
|
||||
|
||||
valid = isProfileSame(profile);
|
||||
|
||||
LOG.debug("isThisProfileSet: valid={}", valid);
|
||||
|
||||
if (valid) {
|
||||
basalProfileChanged = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
noData = true;
|
||||
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("Basal profile NO DATA");
|
||||
}
|
||||
|
||||
isBasalProfileInvalid = !valid;
|
||||
|
||||
setRefreshButtonEnabled(true);
|
||||
|
||||
// we don't want to force set profile if we couldn't read the profile (noData)
|
||||
|
||||
return (noData || valid);
|
||||
}
|
||||
|
||||
|
||||
public boolean isThisProfileSet_New(Profile profile) {
|
||||
|
||||
LOG.debug("isThisProfileSet: basalInitalized={}", getMDTPumpStatus().basalProfileStatus);
|
||||
|
||||
if (getMDTPumpStatus().basalProfileStatus != BasalProfileStatus.ProfileOK)
|
||||
return true;
|
||||
|
||||
return isProfileSame(profile);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -560,8 +560,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
rawHistoryPage.dumpToDebug();
|
||||
|
||||
List<PumpHistoryEntry> medtronicHistoryEntries = pumpHistoryDecoder.processPageAndCreateRecords(
|
||||
rawHistoryPage, false, PumpHistoryEntry.class);
|
||||
List<PumpHistoryEntry> medtronicHistoryEntries = pumpHistoryDecoder
|
||||
.processPageAndCreateRecords(rawHistoryPage);
|
||||
|
||||
LOG.debug("getPumpHistory: Found {} history entries.", medtronicHistoryEntries.size());
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
|||
* <p>
|
||||
* Author: Andy {andy@atech-software.com}
|
||||
*/
|
||||
public abstract class MedtronicHistoryDecoder {
|
||||
public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> implements MedtronicHistoryDecoderInterface<T> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MedtronicHistoryDecoder.class);
|
||||
|
||||
|
@ -51,8 +51,9 @@ public abstract class MedtronicHistoryDecoder {
|
|||
}
|
||||
|
||||
|
||||
public abstract RecordDecodeStatus decodeRecord(MedtronicHistoryEntry record);
|
||||
// public abstract <E extends MedtronicHistoryEntry> Class<E> getHistoryEntryClass();
|
||||
|
||||
// public abstract RecordDecodeStatus decodeRecord(T record);
|
||||
|
||||
public abstract void postProcess();
|
||||
|
||||
|
@ -92,7 +93,7 @@ public abstract class MedtronicHistoryDecoder {
|
|||
|
||||
// TODO_ extend this to also use bigger pages (for now we support only 1024
|
||||
// pages)
|
||||
public List<Byte> checkPage(RawHistoryPage page, boolean partial) throws RuntimeException {
|
||||
private List<Byte> checkPage(RawHistoryPage page, boolean partial) throws RuntimeException {
|
||||
List<Byte> byteList = new ArrayList<Byte>();
|
||||
|
||||
// if (!partial && page.getData().length != 1024 /* page.commandType.getRecordLength() */) {
|
||||
|
@ -120,9 +121,8 @@ public abstract class MedtronicHistoryDecoder {
|
|||
// public abstract List<? extends MedtronicHistoryEntry> processPageAndCreateRecords(RawHistoryPage page,
|
||||
// boolean partial) throws Exception;
|
||||
|
||||
public <E extends MedtronicHistoryEntry> List<E> processPageAndCreateRecords(RawHistoryPage rawHistoryPage,
|
||||
Class<E> clazz) throws Exception {
|
||||
return processPageAndCreateRecords(rawHistoryPage, false, clazz);
|
||||
public List<T> processPageAndCreateRecords(RawHistoryPage rawHistoryPage) {
|
||||
return processPageAndCreateRecords(rawHistoryPage, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -213,12 +213,19 @@ public abstract class MedtronicHistoryDecoder {
|
|||
}
|
||||
|
||||
|
||||
public <E extends MedtronicHistoryEntry> List<E> processPageAndCreateRecords(RawHistoryPage rawHistoryPage,
|
||||
boolean partial, Class<E> clazz) {
|
||||
List<Byte> dataClear = checkPage(rawHistoryPage, partial);
|
||||
List<E> records = createRecords(dataClear, clazz);
|
||||
// public List<T> processPageAndCreateRecords(RawHistoryPage rawHistoryPage) {
|
||||
// return processPageAndCreateRecords(rawHistoryPage, false, getHistoryEntryClass());
|
||||
// }
|
||||
|
||||
for (MedtronicHistoryEntry record : records) {
|
||||
// public List<T> processPageAndCreateRecords(RawHistoryPage rawHistoryPage, boolean partial) {
|
||||
// return processPageAndCreateRecords(rawHistoryPage, partial, getHistoryEntryClass());
|
||||
// }
|
||||
|
||||
private List<T> processPageAndCreateRecords(RawHistoryPage rawHistoryPage, boolean partial) {
|
||||
List<Byte> dataClear = checkPage(rawHistoryPage, partial);
|
||||
List<T> records = createRecords(dataClear);
|
||||
|
||||
for (T record : records) {
|
||||
decodeRecord(record);
|
||||
}
|
||||
|
||||
|
@ -227,7 +234,6 @@ public abstract class MedtronicHistoryDecoder {
|
|||
return records;
|
||||
}
|
||||
|
||||
|
||||
protected abstract <E extends MedtronicHistoryEntry> List<E> createRecords(List<Byte> dataClear, Class<E> clazz);
|
||||
// public abstract List<T> createRecords(List<Byte> dataClear);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by andy on 3/10/19.
|
||||
*/
|
||||
|
||||
public interface MedtronicHistoryDecoderInterface<T> {
|
||||
|
||||
RecordDecodeStatus decodeRecord(T record);
|
||||
|
||||
|
||||
List<T> createRecords(List<Byte> dataClear);
|
||||
|
||||
}
|
|
@ -10,7 +10,6 @@ import org.slf4j.LoggerFactory;
|
|||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.MedtronicHistoryDecoder;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.MedtronicHistoryEntry;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.RecordDecodeStatus;
|
||||
|
||||
/**
|
||||
|
@ -35,7 +34,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.RecordDeco
|
|||
* Author: Andy {andy@atech-software.com}
|
||||
*/
|
||||
|
||||
public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
||||
public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder<CGMSHistoryEntry> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MedtronicCGMSHistoryDecoder.class);
|
||||
|
||||
|
@ -46,7 +45,17 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
}
|
||||
|
||||
|
||||
public RecordDecodeStatus decodeRecord(MedtronicHistoryEntry entryIn) {
|
||||
// @Override
|
||||
// public Class<CGMSHistoryEntry> getHistoryEntryClass() {
|
||||
// return CGMSHistoryEntry.class;
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public Class getHistoryEntryClass() {
|
||||
// return CGMSHistoryEntry.class;
|
||||
// }
|
||||
|
||||
public RecordDecodeStatus decodeRecord(CGMSHistoryEntry entryIn) {
|
||||
CGMSHistoryEntry precord = (CGMSHistoryEntry)entryIn;
|
||||
try {
|
||||
return decodeRecord(precord, false);
|
||||
|
@ -110,7 +119,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
}
|
||||
|
||||
|
||||
protected <E extends MedtronicHistoryEntry> List<E> createRecords(List<Byte> dataClearInput, Class<E> clazz) {
|
||||
public List<CGMSHistoryEntry> createRecords(List<Byte> dataClearInput) {
|
||||
// List<MinimedHistoryEntry> listRecords = new
|
||||
// ArrayList<MinimedHistoryEntry>();
|
||||
|
||||
|
@ -126,7 +135,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
int counter = 0;
|
||||
int record = 0;
|
||||
|
||||
List<E> outList = new ArrayList<E>();
|
||||
List<CGMSHistoryEntry> outList = new ArrayList<CGMSHistoryEntry>();
|
||||
|
||||
// create CGMS entries (without dates)
|
||||
do {
|
||||
|
@ -156,7 +165,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
|
||||
// System.out.println("Record: " + pe);
|
||||
|
||||
outList.add((E)pe);
|
||||
outList.add(pe);
|
||||
} else {
|
||||
List<Byte> listRawData = new ArrayList<Byte>();
|
||||
listRawData.add((byte)opCode);
|
||||
|
@ -174,7 +183,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
|
||||
// System.out.println("Record: " + pe);
|
||||
|
||||
outList.add((E)pe);
|
||||
outList.add(pe);
|
||||
}
|
||||
} else {
|
||||
CGMSHistoryEntry pe = new CGMSHistoryEntry();
|
||||
|
@ -188,7 +197,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
|
||||
// System.out.println("Record: " + pe);
|
||||
|
||||
outList.add((E)pe);
|
||||
outList.add(pe);
|
||||
}
|
||||
|
||||
} while (counter < dataClear.size());
|
||||
|
|
|
@ -46,7 +46,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
|||
* Author: Andy {andy@atech-software.com}
|
||||
*/
|
||||
|
||||
public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
||||
public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHistoryEntry> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MedtronicPumpHistoryDecoder.class);
|
||||
|
||||
|
@ -64,7 +64,12 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
}
|
||||
|
||||
|
||||
protected <E extends MedtronicHistoryEntry> List<E> createRecords(List<Byte> dataClear, Class<E> clazz) {
|
||||
// @Override
|
||||
// public Class<PumpHistoryEntry> getHistoryEntryClass() {
|
||||
// return PumpHistoryEntry.class;
|
||||
// }
|
||||
|
||||
public List<PumpHistoryEntry> createRecords(List<Byte> dataClear) {
|
||||
prepareStatistics();
|
||||
|
||||
int counter = 0;
|
||||
|
@ -72,7 +77,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
boolean incompletePacket = false;
|
||||
deviceType = MedtronicUtil.getMedtronicPumpModel();
|
||||
|
||||
List<E> outList = new ArrayList<E>();
|
||||
List<PumpHistoryEntry> outList = new ArrayList<PumpHistoryEntry>();
|
||||
String skipped = null;
|
||||
int elementStart = 0;
|
||||
|
||||
|
@ -193,7 +198,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
|
||||
if (decoded == RecordDecodeStatus.OK) // we add only OK records, all others are ignored
|
||||
{
|
||||
outList.add((E)pe);
|
||||
outList.add(pe);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,7 +208,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
}
|
||||
|
||||
|
||||
public RecordDecodeStatus decodeRecord(MedtronicHistoryEntry entryIn) {
|
||||
public RecordDecodeStatus decodeRecord(PumpHistoryEntry entryIn) {
|
||||
PumpHistoryEntry precord = (PumpHistoryEntry)entryIn;
|
||||
try {
|
||||
return decodeRecord(entryIn, false);
|
||||
|
@ -214,19 +219,6 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
}
|
||||
|
||||
|
||||
public <E extends MedtronicHistoryEntry> List<E> getTypedList(List<? extends MedtronicHistoryEntry> list,
|
||||
Class<E> clazz) {
|
||||
|
||||
List<E> listOut = new ArrayList<>();
|
||||
|
||||
for (MedtronicHistoryEntry medtronicHistoryEntry : list) {
|
||||
listOut.add((E)medtronicHistoryEntry);
|
||||
}
|
||||
|
||||
return listOut;
|
||||
}
|
||||
|
||||
|
||||
public RecordDecodeStatus decodeRecord(MedtronicHistoryEntry entryIn, boolean x) {
|
||||
// FIXME
|
||||
// TODO
|
||||
|
@ -245,6 +237,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
case DailyTotals522:
|
||||
case DailyTotals523:
|
||||
case DailyTotals515:
|
||||
case EndResultTotals:
|
||||
return decodeDailyTotals(entry); // Not supported at the moment
|
||||
|
||||
case ChangeBasalPattern:
|
||||
|
@ -380,9 +373,9 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
decodeBolus(entry);
|
||||
return RecordDecodeStatus.OK;
|
||||
|
||||
case EndResultTotals:
|
||||
decodeEndResultTotals(entry);
|
||||
return RecordDecodeStatus.OK;
|
||||
// case EndResultTotals:
|
||||
// decodeEndResultTotals(entry);
|
||||
// return RecordDecodeStatus.OK;
|
||||
|
||||
case BatteryChange:
|
||||
decodeBatteryActivity(entry);
|
||||
|
|
|
@ -137,7 +137,7 @@ public class MedtronicUIPostprocessor {
|
|||
Duration dur = new Duration(clockDTO.localDeviceTime.toDateTime(DateTimeZone.UTC),
|
||||
clockDTO.pumpTime.toDateTime(DateTimeZone.UTC));
|
||||
|
||||
clockDTO.timeDifference = dur.getStandardSeconds();
|
||||
clockDTO.timeDifference = (int)dur.getStandardSeconds();
|
||||
|
||||
MedtronicUtil.setPumpTime(clockDTO);
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.joda.time.Minutes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -22,10 +24,10 @@ import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpH
|
|||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntryType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryResult;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.ClockDTO;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.DailyTotalsDTO;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||
|
||||
//import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
|
||||
|
||||
|
@ -49,6 +51,7 @@ public class MedtronicHistoryData {
|
|||
private int basalProfileChangedInternally = 0;
|
||||
|
||||
private Gson gsonPretty;
|
||||
private List<PumpHistoryEntry> fakeTBRs;
|
||||
|
||||
|
||||
public MedtronicHistoryData() {
|
||||
|
@ -120,7 +123,7 @@ public class MedtronicHistoryData {
|
|||
|
||||
}
|
||||
|
||||
TBRs = processTBRs(TBRs);
|
||||
TBRs = preProcessTBRs(TBRs);
|
||||
|
||||
newHistory2.addAll(TBRs);
|
||||
|
||||
|
@ -204,9 +207,6 @@ public class MedtronicHistoryData {
|
|||
// TODO This logic might not be working correctly
|
||||
public boolean isPumpSuspended(Boolean wasPumpSuspended) {
|
||||
|
||||
// if (true)
|
||||
// return false;
|
||||
|
||||
List<PumpHistoryEntry> newAndAll = new ArrayList<>();
|
||||
|
||||
if (!isCollectionEmpty(this.allHistory)) {
|
||||
|
@ -222,6 +222,8 @@ public class MedtronicHistoryData {
|
|||
|
||||
this.sort(newAndAll);
|
||||
|
||||
List<PumpHistoryEntry> newAndAll2 = filterPumpSuspend(newAndAll);
|
||||
|
||||
List<PumpHistoryEntry> items = getFilteredItems(newAndAll, //
|
||||
PumpHistoryEntryType.Bolus, //
|
||||
PumpHistoryEntryType.TempBasalCombined, //
|
||||
|
@ -244,83 +246,32 @@ public class MedtronicHistoryData {
|
|||
pumpHistoryEntryType == PumpHistoryEntryType.PumpResume || //
|
||||
pumpHistoryEntryType == PumpHistoryEntryType.Prime);
|
||||
|
||||
// if (wasPumpSuspended == null) { // suspension status not known
|
||||
//
|
||||
// List<PumpHistoryEntry> items = getFilteredItems(PumpHistoryEntryType.Bolus, //
|
||||
// PumpHistoryEntryType.TempBasalCombined, //
|
||||
// PumpHistoryEntryType.Prime, //
|
||||
// PumpHistoryEntryType.PumpSuspend, //
|
||||
// PumpHistoryEntryType.PumpResume, //
|
||||
// PumpHistoryEntryType.Rewind, //
|
||||
// PumpHistoryEntryType.NoDeliveryAlarm, //
|
||||
// PumpHistoryEntryType.BasalProfileStart);
|
||||
//
|
||||
// if (items.size() == 0)
|
||||
// return wasPumpSuspended == null ? false : wasPumpSuspended;
|
||||
//
|
||||
// PumpHistoryEntry pumpHistoryEntry = items.get(0);
|
||||
//
|
||||
// return !(pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.TempBasalCombined || //
|
||||
// pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.BasalProfileStart || //
|
||||
// pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.Bolus || //
|
||||
// pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.PumpResume);
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// List<PumpHistoryEntry> items = getFilteredItems(PumpHistoryEntryType.Bolus, //
|
||||
// PumpHistoryEntryType.TempBasalCombined, //
|
||||
// PumpHistoryEntryType.Prime, //
|
||||
// PumpHistoryEntryType.PumpSuspend, //
|
||||
// PumpHistoryEntryType.PumpResume, //
|
||||
// PumpHistoryEntryType.Rewind, //
|
||||
// PumpHistoryEntryType.NoDeliveryAlarm, //
|
||||
// PumpHistoryEntryType.BasalProfileStart);
|
||||
//
|
||||
// if (wasPumpSuspended) {
|
||||
//
|
||||
// if (items.size() == 0)
|
||||
// return wasPumpSuspended == null ? false : wasPumpSuspended;
|
||||
//
|
||||
// PumpHistoryEntry pumpHistoryEntry = items.get(0);
|
||||
//
|
||||
// if (pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.TempBasalCombined || //
|
||||
// pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.BasalProfileStart || //
|
||||
// pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.Bolus || //
|
||||
// pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.PumpResume)
|
||||
// return false;
|
||||
// else
|
||||
// return true;
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// if (items.size() == 0)
|
||||
// return wasPumpSuspended == null ? false : wasPumpSuspended;
|
||||
//
|
||||
// PumpHistoryEntry pumpHistoryEntry = items.get(0);
|
||||
//
|
||||
// if (pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.NoDeliveryAlarm || //
|
||||
// pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.PumpSuspend || //
|
||||
// pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.Prime)
|
||||
// return true;
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// return false;
|
||||
|
||||
private List<PumpHistoryEntry> filterPumpSuspend(List<PumpHistoryEntry> newAndAll) {
|
||||
|
||||
if (newAndAll.size() < 11) {
|
||||
return newAndAll;
|
||||
}
|
||||
|
||||
List<PumpHistoryEntry> newAndAllOut = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
newAndAllOut.add(newAndAll.get(i));
|
||||
}
|
||||
|
||||
return newAndAllOut;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process History Data: Boluses(Treatments), TDD, TBRs, Suspend-Resume (or other pump stops: battery, prime)
|
||||
*/
|
||||
|
||||
public void processNewHistoryData() {
|
||||
|
||||
// TDD
|
||||
List<PumpHistoryEntry> tdds = getFilteredListByLastRecord(getTDDType());
|
||||
List<PumpHistoryEntry> tdds = getFilteredListByLastRecord(PumpHistoryEntryType.EndResultTotals, getTDDType());
|
||||
|
||||
LOG.debug("ProcessHistoryData: TDD [count={}, items={}]", tdds.size(), gsonPretty.toJson(tdds));
|
||||
|
||||
|
@ -331,11 +282,11 @@ public class MedtronicHistoryData {
|
|||
// Bolus
|
||||
List<PumpHistoryEntry> treatments = getFilteredListByLastRecord(PumpHistoryEntryType.Bolus);
|
||||
|
||||
LOG.debug("ProcessHistoryData: Bolus [count={}, items=", treatments.size());
|
||||
LOG.debug("ProcessHistoryData: Bolus [count={}, itemsCount={}]", treatments.size());
|
||||
showLogs(null, gsonPretty.toJson(treatments));
|
||||
|
||||
if (treatments.size() > 0) {
|
||||
// processTreatments(treatments);
|
||||
// processBoluses(treatments);
|
||||
}
|
||||
|
||||
// TBR
|
||||
|
@ -345,14 +296,28 @@ public class MedtronicHistoryData {
|
|||
showLogs(null, gsonPretty.toJson(tbrs));
|
||||
|
||||
if (tbrs.size() > 0) {
|
||||
// processTreatments(treatments);
|
||||
// processTBRs(tbrs);
|
||||
}
|
||||
|
||||
// Fake TBR
|
||||
// Suspends (for suspends/resume, fakeTBR)
|
||||
List<PumpHistoryEntry> suspends = getSuspends();
|
||||
|
||||
LOG.debug("ProcessHistoryData: FakeTBRs (suspend/resume) [count={}, items=", suspends.size());
|
||||
showLogs(null, gsonPretty.toJson(suspends));
|
||||
|
||||
if (suspends.size() > 0) {
|
||||
// processSuspends(treatments);
|
||||
}
|
||||
}
|
||||
|
||||
ClockDTO pumpTime;
|
||||
|
||||
public void processTDDs(List<PumpHistoryEntry> tdds) {
|
||||
|
||||
public void processTDDs(List<PumpHistoryEntry> tddsIn) {
|
||||
|
||||
List<PumpHistoryEntry> tdds = filterTDDs(tddsIn);
|
||||
|
||||
pumpTime = MedtronicUtil.getPumpTime();
|
||||
|
||||
LOG.error(getLogPrefix() + "TDDs found: {}. Not processed.\n{}", tdds.size(), gsonPretty.toJson(tdds));
|
||||
|
||||
|
@ -390,6 +355,66 @@ public class MedtronicHistoryData {
|
|||
}
|
||||
|
||||
|
||||
// TODO needs to be implemented
|
||||
public void processBoluses(List<PumpHistoryEntry> boluses) {
|
||||
|
||||
int dateDifference = getOldestDateDifference(boluses);
|
||||
|
||||
// List<Treatment> treatmentsFromHistory = TreatmentsPlugin.getPlugin().getTreatmentsFromHistoryXMinutesAgo(
|
||||
// dateDifference);
|
||||
|
||||
for (PumpHistoryEntry treatment : boluses) {
|
||||
|
||||
LOG.debug("TOE. Treatment: " + treatment);
|
||||
long inLocalTime = tryToGetByLocalTime(treatment.atechDateTime);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO needs to be implemented
|
||||
public void processTBRs(List<PumpHistoryEntry> treatments) {
|
||||
|
||||
int dateDifference = getOldestDateDifference(treatments);
|
||||
|
||||
// List<Treatment> treatmentsFromHistory = TreatmentsPlugin.getPlugin().getTreatmentsFromHistoryXMinutesAgo(
|
||||
// dateDifference);
|
||||
|
||||
for (PumpHistoryEntry treatment : treatments) {
|
||||
|
||||
LOG.debug("TOE. Treatment: " + treatment);
|
||||
long inLocalTime = tryToGetByLocalTime(treatment.atechDateTime);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// TODO needs to be implemented
|
||||
public void processSuspends(List<PumpHistoryEntry> treatments) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// TODO needs to be implemented
|
||||
public List<PumpHistoryEntry> getSuspends() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
private List<PumpHistoryEntry> filterTDDs(List<PumpHistoryEntry> tdds) {
|
||||
List<PumpHistoryEntry> tddsOut = new ArrayList<>();
|
||||
|
||||
for (PumpHistoryEntry tdd : tdds) {
|
||||
if (tdd.getEntryType() != PumpHistoryEntryType.EndResultTotals) {
|
||||
tddsOut.add(tdd);
|
||||
}
|
||||
}
|
||||
|
||||
return tddsOut.size() == 0 ? tdds : tddsOut;
|
||||
}
|
||||
|
||||
|
||||
private TDD findTDD(long atechDateTime, List<TDD> tddsDb) {
|
||||
|
||||
for (TDD tdd : tddsDb) {
|
||||
|
@ -403,9 +428,42 @@ public class MedtronicHistoryData {
|
|||
}
|
||||
|
||||
|
||||
private void processTreatments(List<PumpHistoryEntry> treatments) {
|
||||
private long tryToGetByLocalTime(long atechDateTime) {
|
||||
|
||||
TreatmentsPlugin.getPlugin().getTreatmentsFromHistory();
|
||||
LocalDateTime ldt = DateTimeUtil.toLocalDateTime(atechDateTime);
|
||||
|
||||
LOG.debug("TOE. Time of Entry: " + atechDateTime);
|
||||
LOG.debug("TOE. Clock Pump: " + pumpTime.pumpTime.toString("HH:mm:ss"));
|
||||
LOG.debug("TOE. LocalTime: " + pumpTime.localDeviceTime.toString("HH:mm:ss"));
|
||||
LOG.debug("TOE. Difference(s): " + pumpTime.timeDifference);
|
||||
|
||||
ldt.plusSeconds(pumpTime.timeDifference);
|
||||
|
||||
LOG.debug("TOE. New Time Of Entry: " + ldt.toString("HH:mm:ss"));
|
||||
|
||||
return ldt.toDate().getTime();
|
||||
|
||||
// return 0;
|
||||
}
|
||||
|
||||
|
||||
private int getOldestDateDifference(List<PumpHistoryEntry> treatments) {
|
||||
|
||||
long dt = Long.MAX_VALUE;
|
||||
|
||||
for (PumpHistoryEntry treatment : treatments) {
|
||||
|
||||
if (treatment.atechDateTime < dt) {
|
||||
dt = treatment.atechDateTime;
|
||||
}
|
||||
}
|
||||
|
||||
LocalDateTime d = DateTimeUtil.toLocalDateTime(dt);
|
||||
d.minusMinutes(5);
|
||||
|
||||
Minutes minutes = Minutes.minutesBetween(d, new LocalDateTime());
|
||||
|
||||
return minutes.getMinutes();
|
||||
|
||||
}
|
||||
|
||||
|
@ -422,12 +480,6 @@ public class MedtronicHistoryData {
|
|||
//
|
||||
// }
|
||||
|
||||
// public List<PumpHistoryEntry> getTDDs() {
|
||||
//
|
||||
// return getFilteredListByLastRecord(getTDDType());
|
||||
//
|
||||
// }
|
||||
|
||||
private PumpHistoryEntryType getTDDType() {
|
||||
|
||||
switch (MedtronicUtil.getMedtronicPumpModel()) {
|
||||
|
@ -454,15 +506,6 @@ public class MedtronicHistoryData {
|
|||
}
|
||||
|
||||
|
||||
public List<PumpHistoryEntry> getTreatments() {
|
||||
|
||||
return getFilteredListByLastRecord( //
|
||||
PumpHistoryEntryType.Bolus, //
|
||||
PumpHistoryEntryType.TempBasalCombined);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* entryType == PumpHistoryEntryType.Bolus || // Treatments
|
||||
* entryType == PumpHistoryEntryType.TempBasalRate || //
|
||||
|
@ -589,7 +632,7 @@ public class MedtronicHistoryData {
|
|||
}
|
||||
|
||||
|
||||
private List<PumpHistoryEntry> processTBRs(List<PumpHistoryEntry> TBRs_Input) {
|
||||
private List<PumpHistoryEntry> preProcessTBRs(List<PumpHistoryEntry> TBRs_Input) {
|
||||
List<PumpHistoryEntry> TBRs = new ArrayList<>();
|
||||
|
||||
Map<String, PumpHistoryEntry> map = new HashMap<>();
|
||||
|
|
|
@ -12,5 +12,7 @@ public class ClockDTO {
|
|||
|
||||
public LocalDateTime pumpTime;
|
||||
|
||||
public long timeDifference; // s
|
||||
//public Duration timeDifference;
|
||||
|
||||
public int timeDifference; // s
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
package info.nightscout.androidaps.plugins.treatments;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
@ -41,16 +41,16 @@ import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
|||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
||||
import info.nightscout.androidaps.plugins.general.overview.Dialogs.ErrorHelperActivity;
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
|
@ -58,10 +58,12 @@ import info.nightscout.androidaps.utils.T;
|
|||
* Created by mike on 05.08.2016.
|
||||
*/
|
||||
public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(L.DATATREATMENTS);
|
||||
|
||||
private static TreatmentsPlugin treatmentsPlugin;
|
||||
|
||||
|
||||
public static TreatmentsPlugin getPlugin() {
|
||||
if (treatmentsPlugin == null)
|
||||
treatmentsPlugin = new TreatmentsPlugin();
|
||||
|
@ -79,18 +81,15 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
private final Intervals<TempTarget> tempTargets = new OverlappingIntervals<>();
|
||||
private final ProfileIntervals<ProfileSwitch> profiles = new ProfileIntervals<>();
|
||||
|
||||
|
||||
public TreatmentsPlugin() {
|
||||
super(new PluginDescription()
|
||||
.mainType(PluginType.TREATMENT)
|
||||
.fragmentClass(TreatmentsFragment.class.getName())
|
||||
.pluginName(R.string.treatments)
|
||||
.shortName(R.string.treatments_shortname)
|
||||
.alwaysEnabled(true)
|
||||
.description(R.string.description_treatments)
|
||||
);
|
||||
super(new PluginDescription().mainType(PluginType.TREATMENT).fragmentClass(TreatmentsFragment.class.getName())
|
||||
.pluginName(R.string.treatments).shortName(R.string.treatments_shortname).alwaysEnabled(true)
|
||||
.description(R.string.description_treatments));
|
||||
this.service = new TreatmentService();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
MainApp.bus().register(this);
|
||||
|
@ -102,35 +101,39 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
super.onStart();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
MainApp.bus().register(this);
|
||||
}
|
||||
|
||||
|
||||
public TreatmentService getService() {
|
||||
return this.service;
|
||||
}
|
||||
|
||||
|
||||
private void initializeTreatmentData() {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("initializeTreatmentData");
|
||||
double dia = Constants.defaultDIA;
|
||||
if (ConfigBuilderPlugin.getPlugin() != null && ProfileFunctions.getInstance().getProfile() != null)
|
||||
dia = ProfileFunctions.getInstance().getProfile().getDia();
|
||||
long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
|
||||
long fromMills = (long)(System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
|
||||
synchronized (treatments) {
|
||||
treatments.clear();
|
||||
treatments.addAll(getService().getTreatmentDataFromTime(fromMills, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void initializeTempBasalData() {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("initializeTempBasalData");
|
||||
double dia = Constants.defaultDIA;
|
||||
if (ConfigBuilderPlugin.getPlugin() != null && ProfileFunctions.getInstance().getProfile() != null)
|
||||
dia = ProfileFunctions.getInstance().getProfile().getDia();
|
||||
long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
|
||||
long fromMills = (long)(System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
|
||||
|
||||
synchronized (tempBasals) {
|
||||
tempBasals.reset().add(MainApp.getDbHelper().getTemporaryBasalsDataFromTime(fromMills, false));
|
||||
|
@ -138,13 +141,14 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
|
||||
}
|
||||
|
||||
|
||||
private void initializeExtendedBolusData() {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("initializeExtendedBolusData");
|
||||
double dia = Constants.defaultDIA;
|
||||
if (ConfigBuilderPlugin.getPlugin() != null && ProfileFunctions.getInstance().getProfile() != null)
|
||||
dia = ProfileFunctions.getInstance().getProfile().getDia();
|
||||
long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
|
||||
long fromMills = (long)(System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
|
||||
|
||||
synchronized (extendedBoluses) {
|
||||
extendedBoluses.reset().add(MainApp.getDbHelper().getExtendedBolusDataFromTime(fromMills, false));
|
||||
|
@ -152,6 +156,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
|
||||
}
|
||||
|
||||
|
||||
private void initializeTempTargetData() {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("initializeTempTargetData");
|
||||
|
@ -161,6 +166,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void initializeProfileSwitchData() {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("initializeProfileSwitchData");
|
||||
|
@ -169,11 +175,13 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IobTotal getLastCalculationTreatments() {
|
||||
return lastTreatmentCalculation;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IobTotal getCalculationToTimeTreatments(long time) {
|
||||
IobTotal total = new IobTotal(time);
|
||||
|
@ -184,15 +192,17 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
|
||||
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
|
||||
if (insulinInterface == null)
|
||||
return total;
|
||||
return total;
|
||||
|
||||
double dia = profile.getDia();
|
||||
|
||||
synchronized (treatments) {
|
||||
for (Integer pos = 0; pos < treatments.size(); pos++) {
|
||||
Treatment t = treatments.get(pos);
|
||||
if (!t.isValid) continue;
|
||||
if (t.date > time) continue;
|
||||
if (!t.isValid)
|
||||
continue;
|
||||
if (t.date > time)
|
||||
continue;
|
||||
Iob tIOB = t.iobCalc(time, dia);
|
||||
total.iob += tIOB.iobContrib;
|
||||
total.activity += tIOB.activityContrib;
|
||||
|
@ -202,7 +212,9 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
// instead of dividing the DIA that only worked on the bilinear curves,
|
||||
// multiply the time the treatment is seen active.
|
||||
long timeSinceTreatment = time - t.date;
|
||||
long snoozeTime = t.date + (long) (timeSinceTreatment * SP.getDouble(R.string.key_openapsama_bolussnooze_dia_divisor, 2.0));
|
||||
long snoozeTime = t.date
|
||||
+ (long)(timeSinceTreatment * SP
|
||||
.getDouble(R.string.key_openapsama_bolussnooze_dia_divisor, 2.0));
|
||||
Iob bIOB = t.iobCalc(snoozeTime, dia);
|
||||
total.bolussnooze += bIOB.iobContrib;
|
||||
}
|
||||
|
@ -213,7 +225,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
synchronized (extendedBoluses) {
|
||||
for (Integer pos = 0; pos < extendedBoluses.size(); pos++) {
|
||||
ExtendedBolus e = extendedBoluses.get(pos);
|
||||
if (e.date > time) continue;
|
||||
if (e.date > time)
|
||||
continue;
|
||||
IobTotal calc = e.iobCalc(time);
|
||||
total.plus(calc);
|
||||
}
|
||||
|
@ -221,23 +234,27 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
return total;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateTotalIOBTreatments() {
|
||||
lastTreatmentCalculation = getCalculationToTimeTreatments(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MealData getMealData() {
|
||||
MealData result = new MealData();
|
||||
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if (profile == null) return result;
|
||||
if (profile == null)
|
||||
return result;
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
long dia_ago = now - (Double.valueOf(profile.getDia() * T.hours(1).msecs())).longValue();
|
||||
|
||||
double maxAbsorptionHours = Constants.DEFAULT_MAX_ABSORPTION_TIME;
|
||||
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
|
||||
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)
|
||||
|| SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
|
||||
maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME);
|
||||
} else {
|
||||
maxAbsorptionHours = SP.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME);
|
||||
|
@ -259,7 +276,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
if (t > absorptionTime_ago && t <= now) {
|
||||
if (treatment.carbs >= 1) {
|
||||
result.carbs += treatment.carbs;
|
||||
if(t > result.lastCarbTime)
|
||||
if (t > result.lastCarbTime)
|
||||
result.lastCarbTime = t;
|
||||
}
|
||||
}
|
||||
|
@ -277,6 +294,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Treatment> getTreatmentsFromHistory() {
|
||||
synchronized (treatments) {
|
||||
|
@ -284,6 +302,24 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Treatment> getTreatmentsFromHistoryXMinutesAgo(int minutesAgo) {
|
||||
List<Treatment> in5minback = new ArrayList<>();
|
||||
long time = System.currentTimeMillis();
|
||||
synchronized (treatments) {
|
||||
for (Integer pos = 0; pos < treatments.size(); pos++) {
|
||||
Treatment t = treatments.get(pos);
|
||||
if (!t.isValid)
|
||||
continue;
|
||||
if (t.date <= time && t.date > (time - minutesAgo * 60 * 1000))
|
||||
in5minback.add(t);
|
||||
}
|
||||
return in5minback;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Treatment> getTreatments5MinBackFromHistory(long time) {
|
||||
List<Treatment> in5minback = new ArrayList<>();
|
||||
|
@ -299,6 +335,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getLastBolusTime() {
|
||||
long now = System.currentTimeMillis();
|
||||
|
@ -312,15 +349,17 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("Last bolus time: " + new Date(last).toLocaleString());
|
||||
log.debug("Last bolus time: " + new Date(last).toLocaleString());
|
||||
return last;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isInHistoryRealTempBasalInProgress() {
|
||||
return getRealTempBasalFromHistory(System.currentTimeMillis()) != null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TemporaryBasal getRealTempBasalFromHistory(long time) {
|
||||
synchronized (tempBasals) {
|
||||
|
@ -328,58 +367,66 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isTempBasalInProgress() {
|
||||
return getTempBasalFromHistory(System.currentTimeMillis()) != null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isInHistoryExtendedBoluslInProgress() {
|
||||
return getExtendedBolusFromHistory(System.currentTimeMillis()) != null; //TODO: crosscheck here
|
||||
return getExtendedBolusFromHistory(System.currentTimeMillis()) != null; // TODO: crosscheck here
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventReloadTreatmentData ev) {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("EventReloadTreatmentData");
|
||||
log.debug("EventReloadTreatmentData");
|
||||
initializeTreatmentData();
|
||||
initializeExtendedBolusData();
|
||||
updateTotalIOBTreatments();
|
||||
MainApp.bus().post(ev.next);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
@SuppressWarnings("unused")
|
||||
public void onStatusEvent(final EventReloadTempBasalData ev) {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("EventReloadTempBasalData");
|
||||
log.debug("EventReloadTempBasalData");
|
||||
initializeTempBasalData();
|
||||
updateTotalIOBTempBasals();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IobTotal getLastCalculationTempBasals() {
|
||||
return lastTempBasalsCalculation;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IobTotal getCalculationToTimeTempBasals(long time, Profile profile) {
|
||||
return getCalculationToTimeTempBasals(time, profile, false, 0);
|
||||
}
|
||||
|
||||
|
||||
public IobTotal getCalculationToTimeTempBasals(long time, Profile profile, boolean truncate, long truncateTime) {
|
||||
IobTotal total = new IobTotal(time);
|
||||
|
||||
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
|
||||
if (insulinInterface == null)
|
||||
return total;
|
||||
return total;
|
||||
|
||||
synchronized (tempBasals) {
|
||||
for (Integer pos = 0; pos < tempBasals.size(); pos++) {
|
||||
TemporaryBasal t = tempBasals.get(pos);
|
||||
if (t.date > time) continue;
|
||||
if (t.date > time)
|
||||
continue;
|
||||
IobTotal calc;
|
||||
if(truncate && t.end() > truncateTime){
|
||||
if (truncate && t.end() > truncateTime) {
|
||||
TemporaryBasal dummyTemp = new TemporaryBasal();
|
||||
dummyTemp.copyFrom(t);
|
||||
dummyTemp.cutEndTo(truncateTime);
|
||||
|
@ -387,7 +434,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
} else {
|
||||
calc = t.iobCalc(time, profile);
|
||||
}
|
||||
//log.debug("BasalIOB " + new Date(time) + " >>> " + calc.basaliob);
|
||||
// log.debug("BasalIOB " + new Date(time) + " >>> " + calc.basaliob);
|
||||
total.plus(calc);
|
||||
}
|
||||
}
|
||||
|
@ -396,9 +443,10 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
synchronized (extendedBoluses) {
|
||||
for (Integer pos = 0; pos < extendedBoluses.size(); pos++) {
|
||||
ExtendedBolus e = extendedBoluses.get(pos);
|
||||
if (e.date > time) continue;
|
||||
if (e.date > time)
|
||||
continue;
|
||||
IobTotal calc;
|
||||
if(truncate && e.end() > truncateTime){
|
||||
if (truncate && e.end() > truncateTime) {
|
||||
ExtendedBolus dummyExt = new ExtendedBolus();
|
||||
dummyExt.copyFrom(e);
|
||||
dummyExt.cutEndTo(truncateTime);
|
||||
|
@ -419,6 +467,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
return total;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateTotalIOBTempBasals() {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
|
@ -426,6 +475,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
lastTempBasalsCalculation = getCalculationToTimeTempBasals(DateUtil.now(), profile);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TemporaryBasal getTempBasalFromHistory(long time) {
|
||||
|
@ -438,6 +488,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ExtendedBolus getExtendedBolusFromHistory(long time) {
|
||||
synchronized (extendedBoluses) {
|
||||
|
@ -445,9 +496,10 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean addToHistoryExtendedBolus(ExtendedBolus extendedBolus) {
|
||||
//log.debug("Adding new ExtentedBolus record" + extendedBolus.log());
|
||||
// log.debug("Adding new ExtentedBolus record" + extendedBolus.log());
|
||||
boolean newRecordCreated = MainApp.getDbHelper().createOrUpdate(extendedBolus);
|
||||
if (newRecordCreated) {
|
||||
if (extendedBolus.durationInMinutes == 0) {
|
||||
|
@ -463,6 +515,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
return newRecordCreated;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Intervals<ExtendedBolus> getExtendedBolusesFromHistory() {
|
||||
synchronized (extendedBoluses) {
|
||||
|
@ -470,6 +523,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Intervals<TemporaryBasal> getTemporaryBasalsFromHistory() {
|
||||
synchronized (tempBasals) {
|
||||
|
@ -477,9 +531,10 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean addToHistoryTempBasal(TemporaryBasal tempBasal) {
|
||||
//log.debug("Adding new TemporaryBasal record" + tempBasal.toString());
|
||||
// log.debug("Adding new TemporaryBasal record" + tempBasal.toString());
|
||||
boolean newRecordCreated = MainApp.getDbHelper().createOrUpdate(tempBasal);
|
||||
if (newRecordCreated) {
|
||||
if (tempBasal.durationInMinutes == 0)
|
||||
|
@ -492,6 +547,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
return newRecordCreated;
|
||||
}
|
||||
|
||||
|
||||
// return true if new record is created
|
||||
@Override
|
||||
public boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo, boolean allowUpdate) {
|
||||
|
@ -509,16 +565,20 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
treatment.boluscalc = detailedBolusInfo.boluscalc != null ? detailedBolusInfo.boluscalc.toString() : null;
|
||||
TreatmentService.UpdateReturn creatOrUpdateResult = getService().createOrUpdate(treatment);
|
||||
boolean newRecordCreated = creatOrUpdateResult.newRecord;
|
||||
//log.debug("Adding new Treatment record" + treatment.toString());
|
||||
// log.debug("Adding new Treatment record" + treatment.toString());
|
||||
if (detailedBolusInfo.carbTime != 0) {
|
||||
Treatment carbsTreatment = new Treatment();
|
||||
carbsTreatment.source = detailedBolusInfo.source;
|
||||
carbsTreatment.pumpId = detailedBolusInfo.pumpId; // but this should never happen
|
||||
carbsTreatment.date = detailedBolusInfo.date + detailedBolusInfo.carbTime * 60 * 1000L + 1000L; // add 1 sec to make them different records
|
||||
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;
|
||||
getService().createOrUpdate(carbsTreatment);
|
||||
//log.debug("Adding new Treatment record" + carbsTreatment);
|
||||
// log.debug("Adding new Treatment record" + carbsTreatment);
|
||||
}
|
||||
if (newRecordCreated && detailedBolusInfo.isValid)
|
||||
NSUpload.uploadTreatmentRecord(detailedBolusInfo);
|
||||
|
@ -526,7 +586,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
if (!allowUpdate && !creatOrUpdateResult.success) {
|
||||
log.error("Treatment could not be added to DB", new Exception());
|
||||
|
||||
String status = String.format(MainApp.gs(R.string.error_adding_treatment_message), treatment.insulin, (int) treatment.carbs, DateUtil.dateAndTimeString(treatment.date));
|
||||
String status = String.format(MainApp.gs(R.string.error_adding_treatment_message), treatment.insulin,
|
||||
(int)treatment.carbs, DateUtil.dateAndTimeString(treatment.date));
|
||||
|
||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
||||
i.putExtra("soundid", R.raw.error);
|
||||
|
@ -543,6 +604,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
return newRecordCreated;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long oldestDataAvailable() {
|
||||
long oldestTime = System.currentTimeMillis();
|
||||
|
@ -562,6 +624,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
return oldestTime;
|
||||
}
|
||||
|
||||
|
||||
// TempTargets
|
||||
@Subscribe
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -569,6 +632,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
initializeTempTargetData();
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TempTarget getTempTargetFromHistory() {
|
||||
|
@ -577,6 +641,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TempTarget getTempTargetFromHistory(long time) {
|
||||
|
@ -585,6 +650,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Intervals<TempTarget> getTempTargetsFromHistory() {
|
||||
synchronized (tempTargets) {
|
||||
|
@ -592,13 +658,15 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addToHistoryTempTarget(TempTarget tempTarget) {
|
||||
//log.debug("Adding new TemporaryBasal record" + profileSwitch.log());
|
||||
// log.debug("Adding new TemporaryBasal record" + profileSwitch.log());
|
||||
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
||||
NSUpload.uploadTempTarget(tempTarget);
|
||||
}
|
||||
|
||||
|
||||
// Profile Switch
|
||||
@Subscribe
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -606,13 +674,15 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
initializeProfileSwitchData();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ProfileSwitch getProfileSwitchFromHistory(long time) {
|
||||
synchronized (profiles) {
|
||||
return (ProfileSwitch) profiles.getValueToTime(time);
|
||||
return (ProfileSwitch)profiles.getValueToTime(time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ProfileIntervals<ProfileSwitch> getProfileSwitchesFromHistory() {
|
||||
synchronized (profiles) {
|
||||
|
@ -620,13 +690,13 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addToHistoryProfileSwitch(ProfileSwitch profileSwitch) {
|
||||
//log.debug("Adding new TemporaryBasal record" + profileSwitch.log());
|
||||
// log.debug("Adding new TemporaryBasal record" + profileSwitch.log());
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_SWITCH_MISSING));
|
||||
MainApp.getDbHelper().createOrUpdate(profileSwitch);
|
||||
NSUpload.uploadProfileSwitch(profileSwitch);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
18
app/src/main/res/values/wear.xml
Normal file
18
app/src/main/res/values/wear.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2015 Google Inc. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string-array name="android_wear_capabilities">
|
||||
<item>phone_app_sync_bgs</item>
|
||||
</string-array>
|
||||
</resources>
|
59
app/src/test/java/android/util/Log.java
Normal file
59
app/src/test/java/android/util/Log.java
Normal file
|
@ -0,0 +1,59 @@
|
|||
package android.util;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Created by andy on 3/10/19.
|
||||
*/
|
||||
|
||||
public class Log {
|
||||
|
||||
// 03-10 13:44:42.847 12790-12888/info.nightscout.androidaps D/MedtronicHistoryData:
|
||||
|
||||
static boolean isLoggingEnabled = false;
|
||||
|
||||
|
||||
public static void setLoggingEnabled(boolean enabled) {
|
||||
isLoggingEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
private void writeLog(String type, String tag, String message) {
|
||||
if (isLoggingEnabled) {
|
||||
LocalDateTime ldt = LocalDateTime.now();
|
||||
System.out.println("DEBUG: " + tag + ": " + message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int d(String tag, String msg) {
|
||||
System.out.println("DEBUG: " + tag + ": " + msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public static int v(String tag, String msg) {
|
||||
System.out.println("VERBOSE: " + tag + ": " + msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public static int i(String tag, String msg) {
|
||||
System.out.println("INFO: " + tag + ": " + msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public static int w(String tag, String msg) {
|
||||
System.out.println("WARN: " + tag + ": " + msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public static int e(String tag, String msg) {
|
||||
System.out.println("ERROR: " + tag + ": " + msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// add other methods if required...
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import uk.org.lidalia.slf4jtest.TestLogger;
|
||||
import uk.org.lidalia.slf4jtest.TestLoggerFactory;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.RawHistoryPage;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.MedtronicPumpHistoryDecoder;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
|
||||
|
||||
/**
|
||||
* Created by andy on 3/10/19.
|
||||
*/
|
||||
|
||||
public class MedtronicHistoryDataUTest {
|
||||
|
||||
TestLogger LOGGER = TestLoggerFactory.getTestLogger(MedtronicHistoryDataUTest.class);
|
||||
|
||||
byte[] historyPageData = ByteUtil
|
||||
.createByteArrayFromString("16 00 12 EC 14 47 13 33 00 14 F2 14 47 13 00 16 01 14 F2 14 47 13 33 00 1C C9 15 47 13 00 16 00 1C C9 15 47 13 33 4E 31 D3 15 47 13 00 16 01 31 D3 15 47 13 33 00 1A F1 15 47 13 00 16 00 1A F1 15 47 13 33 50 1D F1 15 47 13 00 16 01 1D F1 15 47 13 33 50 11 D8 16 47 13 00 16 01 11 D8 16 47 13 33 50 31 FB 16 47 13 00 16 01 31 FB 16 47 13 33 50 12 E3 17 47 13 00 16 01 12 E3 17 47 13 33 00 1E FB 17 47 13 00 16 00 1E FB 17 47 13 33 D8 21 FB 17 47 13 00 16 01 21 FB 17 47 13 07 00 00 05 CC 27 93 6D 27 93 05 0C 00 E8 00 00 00 00 05 CC 05 CC 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 33 00 36 C4 00 48 13 00 16 00 36 C4 00 48 13 33 D8 29 C9 00 48 13 00 16 01 29 C9 00 48 13 33 00 12 E7 00 48 13 00 16 00 12 E7 00 48 13 33 BC 19 C9 01 48 13 00 16 01 19 C9 01 48 13 33 00 26 CE 01 48 13 00 16 00 26 CE 01 48 13 33 44 29 CE 01 48 13 00 16 01 29 CE 01 48 13 33 00 13 D3 01 48 13 00 16 00 13 D3 01 48 13 33 64 31 F1 01 48 13 00 16 01 31 F1 01 48 13 33 00 0B F7 01 48 13 00 16 00 0B F7 01 48 13 33 00 12 D8 02 48 13 00 16 01 12 D8 02 48 13 33 00 10 F1 02 48 13 00 16 00 10 F1 02 48 13 33 00 30 C4 03 48 13 00 16 01 30 C4 03 48 13 33 00 04 CA 03 48 13 00 16 00 04 CA 03 48 13 33 00 2F D3 03 48 13 00 16 01 2F D3 03 48 13 33 00 30 D8 03 48 13 00 16 00 30 D8 03 48 13 33 00 13 E7 03 48 13 00 16 01 13 E7 03 48 13 33 00 2E FB 03 48 13 00 16 00 2E FB 03 48 13 19 00 00 C1 04 08 13 07 00 00 04 0C 28 93 6D 28 93 05 0C 00 E8 00 00 00 00 04 0C 04 0C 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 06 3E 03 7A 19 DC 48 49 13 0C 3E 0C E6 08 09 13 07 00 00 01 E4 29 93 6D 29 93 05 0C 00 E8 00 00 00 00 01 E4 01 E4 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 1A 00 13 D2 0D 0A 13 1A 01 28 D2 0D 0A 13 21 00 2A D8 0D 0A 13 03 00 00 00 0E 2D D9 2D 0A 13 33 98 26 DE 0D 4A 13 00 16 01 26 DE 0D 4A 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5D 70");
|
||||
|
||||
MedtronicPumpHistoryDecoder decoder = new MedtronicPumpHistoryDecoder();
|
||||
|
||||
|
||||
// Logger LOGGER = LoggerFactory.getLogger(MedtronicHistoryDataUTest.class);
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
||||
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "trace");
|
||||
|
||||
// final TestAppender appender = new TestAppender();
|
||||
// final Logger logger = Logger.getRootLogger();
|
||||
// logger.addAppender(appender);
|
||||
// try {
|
||||
// Logger.getLogger(MyTest.class).info("Test");
|
||||
// } finally {
|
||||
// logger.removeAppender(appender);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testTBR() throws Exception {
|
||||
|
||||
RawHistoryPage historyPage = new RawHistoryPage();
|
||||
historyPage.appendData(historyPageData);
|
||||
|
||||
List<PumpHistoryEntry> pumpHistoryEntries = decoder.processPageAndCreateRecords(historyPage,
|
||||
PumpHistoryEntry.class);
|
||||
|
||||
System.out.println("PumpHistoryEntries: " + pumpHistoryEntries.size());
|
||||
|
||||
Log.d("Test", "Log.d");
|
||||
LOGGER.debug("Logger.debug");
|
||||
|
||||
for (PumpHistoryEntry pumpHistoryEntry : pumpHistoryEntries) {
|
||||
Log.d("MedtronicHistoryDataUTest", pumpHistoryEntry.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testBolus() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
|
||||
|
@ -90,7 +89,7 @@ public class MedtronicPumpHistoryDecoderUTest {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
// @Test
|
||||
public void decodeDailyTotals515() {
|
||||
|
||||
byte[] data = ByteUtil
|
||||
|
@ -111,7 +110,7 @@ public class MedtronicPumpHistoryDecoderUTest {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
// @Test
|
||||
public void decodeDailyTotals523() {
|
||||
|
||||
byte[] data = new byte[] {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Before;
|
||||
|
@ -14,12 +16,12 @@ import info.SPMocker;
|
|||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.T;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
/**
|
||||
* Created by andy on 6/16/18.
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package info.nightscout.androidaps.utils;
|
||||
|
||||
/**
|
||||
* Created by andy on 3/10/19.
|
||||
*/
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
//import ch.qos.logback.core.read.ListAppender;
|
||||
|
||||
public class LoggerRule implements TestRule {
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* private final ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
|
||||
* private final Logger logger = (Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||
*
|
||||
*
|
||||
* @Override
|
||||
* public Statement apply(Statement base, Description description) {
|
||||
* return new Statement() {
|
||||
*
|
||||
* @Override
|
||||
* public void evaluate() throws Throwable {
|
||||
* setup();
|
||||
* base.evaluate();
|
||||
* teardown();
|
||||
* }
|
||||
* };
|
||||
* }
|
||||
*
|
||||
*
|
||||
* private void setup() {
|
||||
* logger.addAppender(listAppender);
|
||||
* listAppender.start();
|
||||
* }
|
||||
*
|
||||
*
|
||||
* private void teardown() {
|
||||
* listAppender.stop();
|
||||
* listAppender.list.clear();
|
||||
* logger.detachAppender(listAppender);
|
||||
* }
|
||||
*
|
||||
*
|
||||
* public List<String> getMessages() {
|
||||
* return listAppender.list.stream().map(e -> e.getMessage()).collect(Collectors.toList());
|
||||
* }
|
||||
*
|
||||
*
|
||||
* public List<String> getFormattedMessages() {
|
||||
* return listAppender.list.stream().map(e -> e.getFormattedMessage()).collect(Collectors.toList());
|
||||
* }
|
||||
*/
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ apply plugin: 'com.android.application'
|
|||
|
||||
ext {
|
||||
wearableVersion = "2.0.1"
|
||||
playServicesWearable = "10.2.1"
|
||||
}
|
||||
|
||||
def generateGitBuild = { ->
|
||||
|
@ -89,8 +90,8 @@ dependencies {
|
|||
//compile "com.ustwo.android:clockwise-wearable:1.0.2"
|
||||
compileOnly "com.google.android.wearable:wearable:${wearableVersion}"
|
||||
implementation "com.google.android.support:wearable:${wearableVersion}"
|
||||
implementation "com.google.android.gms:play-services-wearable:7.3.0"
|
||||
implementation(name:"ustwo-clockwise-debug", ext:"aar")
|
||||
implementation "com.google.android.gms:play-services-wearable:${playServicesWearable}"
|
||||
implementation(name: "ustwo-clockwise-debug", ext: "aar")
|
||||
implementation "com.android.support:support-v4:27.0.1"
|
||||
implementation 'com.android.support:wear:27.0.1'
|
||||
implementation "me.denley.wearpreferenceactivity:wearpreferenceactivity:0.5.0"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
|
||||
|
||||
<application
|
||||
|
@ -168,9 +168,66 @@
|
|||
<category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service android:name=".data.ListenerService">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
|
||||
<!-- <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> -->
|
||||
<!-- listeners receive events that match the action and data filters -->
|
||||
<action android:name="com.google.android.gms.wearable.CAPABILITY_CHANGED" />
|
||||
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
|
||||
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_data" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_data_resend" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_cancel_bolus" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_confirmactionstring" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_initiateactionstring" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/openwearsettings" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/sendstatustowear" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/sendpreferencestowear" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_basal" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_bolusprogress" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_actionconfirmationrequest" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_changeconfirmationrequest" />
|
||||
<data
|
||||
android:scheme="wear"
|
||||
android:host="*"
|
||||
android:pathPrefix="/nightscout_watch_cancelnotificationrequest" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package info.nightscout.androidaps.data;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
|
@ -10,13 +13,18 @@ import android.os.AsyncTask;
|
|||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.PendingResult;
|
||||
import com.google.android.gms.common.api.ResultCallback;
|
||||
import com.google.android.gms.wearable.CapabilityApi;
|
||||
import com.google.android.gms.wearable.CapabilityInfo;
|
||||
import com.google.android.gms.wearable.ChannelApi;
|
||||
import com.google.android.gms.wearable.DataEvent;
|
||||
import com.google.android.gms.wearable.DataEventBuffer;
|
||||
import com.google.android.gms.wearable.DataMap;
|
||||
|
@ -26,19 +34,18 @@ import com.google.android.gms.wearable.NodeApi;
|
|||
import com.google.android.gms.wearable.Wearable;
|
||||
import com.google.android.gms.wearable.WearableListenerService;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import info.nightscout.androidaps.interaction.AAPSPreferences;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.interaction.AAPSPreferences;
|
||||
import info.nightscout.androidaps.interaction.actions.AcceptActivity;
|
||||
import info.nightscout.androidaps.interaction.actions.CPPActivity;
|
||||
import info.nightscout.androidaps.interaction.utils.SafeParse;
|
||||
import info.nightscout.androidaps.interaction.utils.WearUtil;
|
||||
|
||||
/**
|
||||
* Created by emmablack on 12/26/14.
|
||||
*/
|
||||
public class ListenerService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks,
|
||||
GoogleApiClient.OnConnectionFailedListener {
|
||||
public class ListenerService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ChannelApi.ChannelListener {
|
||||
|
||||
private static final String WEARABLE_DATA_PATH = "/nightscout_watch_data";
|
||||
private static final String WEARABLE_RESEND_PATH = "/nightscout_watch_data_resend";
|
||||
private static final String WEARABLE_CANCELBOLUS_PATH = "/nightscout_watch_cancel_bolus";
|
||||
|
@ -54,7 +61,6 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
public static final String NEW_CHANGECONFIRMATIONREQUEST_PATH = "/nightscout_watch_changeconfirmationrequest";
|
||||
public static final String ACTION_CANCELNOTIFICATION_REQUEST_PATH = "/nightscout_watch_cancelnotificationrequest";
|
||||
|
||||
|
||||
public static final int BOLUS_PROGRESS_NOTIF_ID = 001;
|
||||
public static final int CONFIRM_NOTIF_ID = 002;
|
||||
public static final int CHANGE_NOTIF_ID = 556677;
|
||||
|
@ -65,63 +71,181 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
private static final String ACTION_CONFIRMCHANGE = "com.dexdrip.stephenblack.nightwatch.CONFIRMCHANGE";
|
||||
private static final String ACTION_INITIATE_ACTION = "com.dexdrip.stephenblack.nightwatch.INITIATE_ACTION";
|
||||
|
||||
|
||||
private static final String ACTION_RESEND_BULK = "com.dexdrip.stephenblack.nightwatch.RESEND_BULK_DATA";
|
||||
|
||||
GoogleApiClient googleApiClient;
|
||||
private long lastRequest = 0;
|
||||
private DismissThread confirmThread;
|
||||
private DismissThread bolusprogressThread;
|
||||
private static final String TAG = "ListenerService";
|
||||
|
||||
private DataRequester mDataRequester = null;
|
||||
private static final int GET_CAPABILITIES_TIMEOUT_MS = 5000;
|
||||
|
||||
// Phone
|
||||
private static final String CAPABILITY_PHONE_APP = "phone_app_sync_bgs";
|
||||
private static final String MESSAGE_PATH_PHONE = "/phone_message_path";
|
||||
// Wear
|
||||
private static final String CAPABILITY_WEAR_APP = "wear_app_sync_bgs";
|
||||
private static final String MESSAGE_PATH_WEAR = "/wear_message_path";
|
||||
private String mPhoneNodeId = null;
|
||||
private String localnode = null;
|
||||
private String logPrefix = ""; // "WR: "
|
||||
|
||||
public class DataRequester extends AsyncTask<Void, Void, Void> {
|
||||
Context mContext;
|
||||
|
||||
DataRequester(Context context) {
|
||||
mContext = context;
|
||||
Context mContext;
|
||||
String path;
|
||||
byte[] payload;
|
||||
|
||||
|
||||
DataRequester(Context context, String thispath, byte[] thispayload) {
|
||||
path = thispath;
|
||||
payload = thispayload;
|
||||
// Log.d(TAG, logPrefix + "DataRequester DataRequester: " + thispath + " lastRequest:" + lastRequest);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
if (googleApiClient.isConnected()) {
|
||||
if (System.currentTimeMillis() - lastRequest > 20 * 1000) { // enforce 20-second debounce period
|
||||
lastRequest = System.currentTimeMillis();
|
||||
// Log.d(TAG, logPrefix + "DataRequester: doInBack: " + params);
|
||||
|
||||
NodeApi.GetConnectedNodesResult nodes =
|
||||
Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
|
||||
for (Node node : nodes.getNodes()) {
|
||||
Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), WEARABLE_RESEND_PATH, null);
|
||||
}
|
||||
try {
|
||||
|
||||
forceGoogleApiConnect();
|
||||
DataMap datamap;
|
||||
|
||||
if (isCancelled()) {
|
||||
Log.d(TAG, "doInBackground CANCELLED programmatically");
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
googleApiClient.blockingConnect(15, TimeUnit.SECONDS);
|
||||
if (googleApiClient.isConnected()) {
|
||||
if (System.currentTimeMillis() - lastRequest > 20 * 1000) { // enforce 20-second debounce period
|
||||
|
||||
if (googleApiClient != null) {
|
||||
if (!googleApiClient.isConnected())
|
||||
googleApiClient.blockingConnect(15, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
// this code might not be needed in this way, but we need to see that later
|
||||
if ((googleApiClient != null) && (googleApiClient.isConnected())) {
|
||||
if ((System.currentTimeMillis() - lastRequest > 20 * 1000)) {
|
||||
|
||||
// enforce 20-second debounce period
|
||||
lastRequest = System.currentTimeMillis();
|
||||
|
||||
NodeApi.GetConnectedNodesResult nodes =
|
||||
Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
|
||||
for (Node node : nodes.getNodes()) {
|
||||
Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), WEARABLE_RESEND_PATH, null);
|
||||
// NodeApi.GetConnectedNodesResult nodes =
|
||||
// Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
|
||||
if (localnode == null || (localnode != null && localnode.isEmpty()))
|
||||
setLocalNodeName();
|
||||
|
||||
CapabilityInfo capabilityInfo = getCapabilities();
|
||||
|
||||
int count = 0;
|
||||
Node phoneNode = null;
|
||||
|
||||
if (capabilityInfo != null) {
|
||||
phoneNode = updatePhoneSyncBgsCapability(capabilityInfo);
|
||||
count = capabilityInfo.getNodes().size();
|
||||
}
|
||||
|
||||
Log.d(TAG, "doInBackground connected. CapabilityApi.GetCapabilityResult mPhoneNodeID="
|
||||
+ (phoneNode != null ? phoneNode.getId() : "") + " count=" + count + " localnode="
|
||||
+ localnode);// KS
|
||||
|
||||
if (count > 0) {
|
||||
|
||||
for (Node node : capabilityInfo.getNodes()) {
|
||||
|
||||
// Log.d(TAG, "doInBackground path: " + path);
|
||||
|
||||
switch (path) {
|
||||
// simple send as is payloads
|
||||
|
||||
case WEARABLE_RESEND_PATH:
|
||||
Wearable.MessageApi.sendMessage(googleApiClient, node.getId(),
|
||||
WEARABLE_RESEND_PATH, null);
|
||||
break;
|
||||
case WEARABLE_DATA_PATH:
|
||||
case WEARABLE_CANCELBOLUS_PATH:
|
||||
case WEARABLE_CONFIRM_ACTIONSTRING_PATH:
|
||||
case WEARABLE_INITIATE_ACTIONSTRING_PATH:
|
||||
case OPEN_SETTINGS:
|
||||
case NEW_STATUS_PATH:
|
||||
case NEW_PREFERENCES_PATH:
|
||||
case BASAL_DATA_PATH:
|
||||
case BOLUS_PROGRESS_PATH:
|
||||
case ACTION_CONFIRMATION_REQUEST_PATH:
|
||||
case NEW_CHANGECONFIRMATIONREQUEST_PATH:
|
||||
case ACTION_CANCELNOTIFICATION_REQUEST_PATH: {
|
||||
Log.w(TAG, logPrefix + "Unhandled path");
|
||||
// sendMessagePayload(node, path, path, payload);
|
||||
}
|
||||
|
||||
default:// SYNC_ALL_DATA
|
||||
// this fall through is messy and non-deterministic for new paths
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
Log.d(TAG, logPrefix + "doInBackground connected but getConnectedNodes returns 0.");
|
||||
|
||||
}
|
||||
} else {
|
||||
// no resend
|
||||
Log.d(TAG, logPrefix + "Inside the timeout, will not be executed");
|
||||
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, logPrefix + "Not connected for sending: api "
|
||||
+ ((googleApiClient == null) ? "is NULL!" : "not null"));
|
||||
if (googleApiClient != null) {
|
||||
googleApiClient.connect();
|
||||
} else {
|
||||
googleApiConnect();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG, logPrefix + "Error executing DataRequester in background. Exception: " + ex.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public CapabilityInfo getCapabilities() {
|
||||
|
||||
CapabilityApi.GetCapabilityResult capabilityResult = Wearable.CapabilityApi.getCapability(googleApiClient,
|
||||
CAPABILITY_PHONE_APP, CapabilityApi.FILTER_REACHABLE).await(GET_CAPABILITIES_TIMEOUT_MS,
|
||||
TimeUnit.MILLISECONDS);
|
||||
|
||||
if (!capabilityResult.getStatus().isSuccess()) {
|
||||
Log.e(TAG, logPrefix + "doInBackground Failed to get capabilities, status: "
|
||||
+ capabilityResult.getStatus().getStatusMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
return capabilityResult.getCapability();
|
||||
|
||||
}
|
||||
|
||||
public class BolusCancelTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
Context mContext;
|
||||
|
||||
|
||||
BolusCancelTask(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
// Log.d(TAG, logPrefix + "BolusCancelTask: doInBack: " + params);
|
||||
|
||||
if (googleApiClient.isConnected()) {
|
||||
NodeApi.GetConnectedNodesResult nodes =
|
||||
Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
|
||||
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
|
||||
for (Node node : nodes.getNodes()) {
|
||||
Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), WEARABLE_CANCELBOLUS_PATH, null);
|
||||
}
|
||||
|
@ -129,8 +253,7 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
} else {
|
||||
googleApiClient.blockingConnect(15, TimeUnit.SECONDS);
|
||||
if (googleApiClient.isConnected()) {
|
||||
NodeApi.GetConnectedNodesResult nodes =
|
||||
Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
|
||||
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
|
||||
for (Node node : nodes.getNodes()) {
|
||||
Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), WEARABLE_CANCELBOLUS_PATH, null);
|
||||
}
|
||||
|
@ -142,32 +265,40 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
}
|
||||
|
||||
public class MessageActionTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
Context mContext;
|
||||
String mActionstring;
|
||||
String mMessagePath;
|
||||
|
||||
|
||||
MessageActionTask(Context context, String messagePath, String actionstring) {
|
||||
mContext = context;
|
||||
mActionstring = actionstring;
|
||||
mMessagePath = messagePath;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
|
||||
// Log.d(TAG, logPrefix + "MessageActionTask: doInBack: " + params);
|
||||
|
||||
forceGoogleApiConnect();
|
||||
|
||||
if (googleApiClient.isConnected()) {
|
||||
NodeApi.GetConnectedNodesResult nodes =
|
||||
Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
|
||||
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
|
||||
for (Node node : nodes.getNodes()) {
|
||||
Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), mMessagePath, mActionstring.getBytes());
|
||||
Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), mMessagePath,
|
||||
mActionstring.getBytes());
|
||||
}
|
||||
|
||||
} else {
|
||||
googleApiClient.blockingConnect(15, TimeUnit.SECONDS);
|
||||
if (googleApiClient.isConnected()) {
|
||||
NodeApi.GetConnectedNodesResult nodes =
|
||||
Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
|
||||
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
|
||||
for (Node node : nodes.getNodes()) {
|
||||
Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), mMessagePath, mActionstring.getBytes());
|
||||
Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), mMessagePath,
|
||||
mActionstring.getBytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,72 +306,153 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void requestData() {
|
||||
new DataRequester(this).execute();
|
||||
sendData(WEARABLE_RESEND_PATH, null);
|
||||
}
|
||||
|
||||
|
||||
public void cancelBolus() {
|
||||
new BolusCancelTask(this).execute();
|
||||
}
|
||||
|
||||
|
||||
private void sendConfirmActionstring(String actionstring) {
|
||||
new MessageActionTask(this, WEARABLE_CONFIRM_ACTIONSTRING_PATH, actionstring).execute();
|
||||
}
|
||||
|
||||
|
||||
private void sendInitiateActionstring(String actionstring) {
|
||||
new MessageActionTask(this, WEARABLE_INITIATE_ACTIONSTRING_PATH, actionstring).execute();
|
||||
}
|
||||
|
||||
public void googleApiConnect() {
|
||||
googleApiClient = new GoogleApiClient.Builder(this)
|
||||
.addConnectionCallbacks(this)
|
||||
.addOnConnectionFailedListener(this)
|
||||
.addApi(Wearable.API)
|
||||
.build();
|
||||
|
||||
private Node updatePhoneSyncBgsCapability(CapabilityInfo capabilityInfo) {
|
||||
// Log.d(TAG, "CapabilityInfo: " + capabilityInfo);
|
||||
|
||||
Set<Node> connectedNodes = capabilityInfo.getNodes();
|
||||
return pickBestNode(connectedNodes);
|
||||
// mPhoneNodeId = pickBestNodeId(connectedNodes);
|
||||
}
|
||||
|
||||
|
||||
private Node pickBestNode(Set<Node> nodes) {
|
||||
Node bestNode = null;
|
||||
// Find a nearby node or pick one arbitrarily
|
||||
for (Node node : nodes) {
|
||||
if (node.isNearby()) {
|
||||
return node;
|
||||
}
|
||||
bestNode = node;
|
||||
}
|
||||
return bestNode;
|
||||
}
|
||||
|
||||
|
||||
private synchronized void sendData(String path, byte[] payload) {
|
||||
// Log.d(TAG, "WR: sendData: path: " + path + ", payload=" + payload);
|
||||
|
||||
if (path == null)
|
||||
return;
|
||||
if (mDataRequester != null) {
|
||||
// Log.d(TAG, logPrefix + "sendData DataRequester != null lastRequest:" +
|
||||
// WearUtil.dateTimeText(lastRequest));
|
||||
if (mDataRequester.getStatus() != AsyncTask.Status.FINISHED) {
|
||||
// Log.d(TAG, logPrefix + "sendData Should be canceled? Let run 'til finished.");
|
||||
// mDataRequester.cancel(true);
|
||||
}
|
||||
// mDataRequester = null;
|
||||
}
|
||||
|
||||
Log.d(TAG, logPrefix + "sendData: execute lastRequest:" + WearUtil.dateTimeText(lastRequest));
|
||||
mDataRequester = (DataRequester)new DataRequester(this, path, payload).execute();
|
||||
// executeTask(mDataRequester);
|
||||
|
||||
// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
// Log.d(TAG, "sendData SDK < M call execute lastRequest:" + WearUtil.dateTimeText(lastRequest));
|
||||
// mDataRequester = (DataRequester) new DataRequester(this, path, payload).execute();
|
||||
// } else {
|
||||
// Log.d(TAG, "sendData SDK >= M call executeOnExecutor lastRequest:" + WearUtil.dateTimeText(lastRequest));
|
||||
// // TODO xdrip executor
|
||||
// mDataRequester = (DataRequester) new DataRequester(this, path, payload).executeOnExecutor(xdrip.executor);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
private void googleApiConnect() {
|
||||
if (googleApiClient != null) {
|
||||
// Remove old listener(s)
|
||||
try {
|
||||
Wearable.ChannelApi.removeListener(googleApiClient, this);
|
||||
} catch (Exception e) {
|
||||
//
|
||||
}
|
||||
try {
|
||||
Wearable.MessageApi.removeListener(googleApiClient, this);
|
||||
} catch (Exception e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
googleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
|
||||
.addOnConnectionFailedListener(this).addApi(Wearable.API).build();
|
||||
Wearable.MessageApi.addListener(googleApiClient, this);
|
||||
}
|
||||
|
||||
|
||||
private void forceGoogleApiConnect() {
|
||||
if ((googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting())
|
||||
|| googleApiClient == null) {
|
||||
try {
|
||||
Log.d(TAG, "forceGoogleApiConnect: forcing google api reconnection");
|
||||
googleApiConnect();
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
// Log.d(TAG, logPrefix + "onStartCommand: Intent: " + intent);
|
||||
|
||||
if (intent != null && ACTION_RESEND.equals(intent.getAction())) {
|
||||
googleApiConnect();
|
||||
requestData();
|
||||
} else if(intent != null && ACTION_CANCELBOLUS.equals(intent.getAction())){
|
||||
} else if (intent != null && ACTION_CANCELBOLUS.equals(intent.getAction())) {
|
||||
googleApiConnect();
|
||||
|
||||
//dismiss notification
|
||||
NotificationManagerCompat notificationManager =
|
||||
NotificationManagerCompat.from(ListenerService.this);
|
||||
// dismiss notification
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(ListenerService.this);
|
||||
notificationManager.cancel(BOLUS_PROGRESS_NOTIF_ID);
|
||||
|
||||
//send cancel-request to phone.
|
||||
// send cancel-request to phone.
|
||||
cancelBolus();
|
||||
|
||||
|
||||
} else if(intent != null && ACTION_CONFIRMATION.equals(intent.getAction())){
|
||||
} else if (intent != null && ACTION_CONFIRMATION.equals(intent.getAction())) {
|
||||
googleApiConnect();
|
||||
|
||||
//dismiss notification
|
||||
NotificationManagerCompat notificationManager =
|
||||
NotificationManagerCompat.from(ListenerService.this);
|
||||
// dismiss notification
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(ListenerService.this);
|
||||
notificationManager.cancel(CONFIRM_NOTIF_ID);
|
||||
|
||||
String actionstring = intent.getStringExtra("actionstring");
|
||||
sendConfirmActionstring(actionstring);
|
||||
|
||||
} else if(intent != null && ACTION_CONFIRMCHANGE.equals(intent.getAction())){
|
||||
} else if (intent != null && ACTION_CONFIRMCHANGE.equals(intent.getAction())) {
|
||||
googleApiConnect();
|
||||
|
||||
//dismiss notification
|
||||
NotificationManagerCompat notificationManager =
|
||||
NotificationManagerCompat.from(ListenerService.this);
|
||||
// dismiss notification
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(ListenerService.this);
|
||||
notificationManager.cancel(CHANGE_NOTIF_ID);
|
||||
|
||||
String actionstring = intent.getStringExtra("actionstring");
|
||||
sendConfirmActionstring(actionstring);
|
||||
|
||||
} else if(intent != null && ACTION_INITIATE_ACTION.equals(intent.getAction())){
|
||||
} else if (intent != null && ACTION_INITIATE_ACTION.equals(intent.getAction())) {
|
||||
googleApiConnect();
|
||||
|
||||
String actionstring = intent.getStringExtra("actionstring");
|
||||
|
@ -256,31 +468,37 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
public void onDataChanged(DataEventBuffer dataEvents) {
|
||||
|
||||
DataMap dataMap;
|
||||
// Log.d(TAG, logPrefix + "onDataChanged: DataEvents=" + dataEvents);
|
||||
|
||||
for (DataEvent event : dataEvents) {
|
||||
|
||||
if (event.getType() == DataEvent.TYPE_CHANGED) {
|
||||
|
||||
|
||||
String path = event.getDataItem().getUri().getPath();
|
||||
|
||||
Log.d(TAG, "WR: onDataChanged: Path: " + path + ", EventDataItem=" + event.getDataItem());
|
||||
|
||||
if (path.equals(OPEN_SETTINGS)) {
|
||||
Intent intent = new Intent(this, AAPSPreferences.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
} else if (path.equals(BOLUS_PROGRESS_PATH)) {
|
||||
int progress = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getInt("progresspercent", 0);
|
||||
String status = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("progressstatus", "");
|
||||
int progress = DataMapItem.fromDataItem(event.getDataItem()).getDataMap()
|
||||
.getInt("progresspercent", 0);
|
||||
String status = DataMapItem.fromDataItem(event.getDataItem()).getDataMap()
|
||||
.getString("progressstatus", "");
|
||||
showBolusProgress(progress, status);
|
||||
} else if (path.equals(ACTION_CONFIRMATION_REQUEST_PATH)) {
|
||||
String title = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("title");
|
||||
String message = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("message");
|
||||
String actionstring = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("actionstring");
|
||||
String actionstring = DataMapItem.fromDataItem(event.getDataItem()).getDataMap()
|
||||
.getString("actionstring");
|
||||
|
||||
if("opencpp".equals(title) && actionstring.startsWith("opencpp")){
|
||||
if ("opencpp".equals(title) && actionstring.startsWith("opencpp")) {
|
||||
String[] act = actionstring.split("\\s+");
|
||||
Intent intent = new Intent(this, CPPActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
//TODO adrian: parse actionstring and add parameters
|
||||
// TODO adrian: parse actionstring and add parameters
|
||||
Bundle params = new Bundle();
|
||||
params.putInt("percentage", SafeParse.stringToInt(act[1]));
|
||||
params.putInt("timeshift", SafeParse.stringToInt(act[2]));
|
||||
|
@ -296,15 +514,15 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
messageIntent.setAction(Intent.ACTION_SEND);
|
||||
messageIntent.putExtra("status", dataMap.toBundle());
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent);
|
||||
} else if (path.equals(BASAL_DATA_PATH)){
|
||||
} else if (path.equals(BASAL_DATA_PATH)) {
|
||||
dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
|
||||
Intent messageIntent = new Intent();
|
||||
messageIntent.setAction(Intent.ACTION_SEND);
|
||||
messageIntent.putExtra("basals", dataMap.toBundle());
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent);
|
||||
} else if (path.equals(NEW_PREFERENCES_PATH)){
|
||||
} else if (path.equals(NEW_PREFERENCES_PATH)) {
|
||||
dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
|
||||
if(dataMap.containsKey("wearcontrol")) {
|
||||
if (dataMap.containsKey("wearcontrol")) {
|
||||
boolean wearcontrol = dataMap.getBoolean("wearcontrol", false);
|
||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
|
@ -314,10 +532,12 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
} else if (path.equals(NEW_CHANGECONFIRMATIONREQUEST_PATH)) {
|
||||
String title = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("title");
|
||||
String message = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("message");
|
||||
String actionstring = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("actionstring");
|
||||
String actionstring = DataMapItem.fromDataItem(event.getDataItem()).getDataMap()
|
||||
.getString("actionstring");
|
||||
notifyChangeRequest(title, message, actionstring);
|
||||
} else if (path.equals(ACTION_CANCELNOTIFICATION_REQUEST_PATH)) {
|
||||
String actionstring = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("actionstring");
|
||||
String actionstring = DataMapItem.fromDataItem(event.getDataItem()).getDataMap()
|
||||
.getString("actionstring");
|
||||
cancelNotificationRequest(actionstring);
|
||||
} else {
|
||||
dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
|
||||
|
@ -330,14 +550,12 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void notifyChangeRequest(String title, String message, String actionstring) {
|
||||
|
||||
Notification.Builder builder =
|
||||
new Notification.Builder(this); //,"AndroidAPS-Openloop");
|
||||
builder.setSmallIcon(R.drawable.notif_icon)
|
||||
.setContentTitle(title)
|
||||
.setContentText(message)
|
||||
.setPriority(Notification.PRIORITY_HIGH);
|
||||
Notification.Builder builder = new Notification.Builder(this); // ,"AndroidAPS-Openloop");
|
||||
builder.setSmallIcon(R.drawable.notif_icon).setContentTitle(title).setContentText(message)
|
||||
.setPriority(Notification.PRIORITY_HIGH);
|
||||
|
||||
// Creates an explicit intent for an Activity in your app
|
||||
Intent intent = new Intent(this, AcceptActivity.class);
|
||||
|
@ -348,62 +566,56 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
params.putString("actionstring", actionstring);
|
||||
intent.putExtras(params);
|
||||
|
||||
PendingIntent resultPendingIntent =
|
||||
PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
builder.setContentIntent(resultPendingIntent);
|
||||
builder.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
|
||||
builder.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 });
|
||||
|
||||
NotificationManager mNotificationManager =
|
||||
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||
// mId allows you to update the notification later on.
|
||||
mNotificationManager.notify(CHANGE_NOTIF_ID, builder.build());
|
||||
}
|
||||
|
||||
|
||||
private void cancelNotificationRequest(String actionstring) {
|
||||
NotificationManager mNotificationManager =
|
||||
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||
mNotificationManager.cancel(CHANGE_NOTIF_ID);
|
||||
}
|
||||
|
||||
|
||||
private void showBolusProgress(int progresspercent, String progresstatus) {
|
||||
Intent cancelIntent = new Intent(this, ListenerService.class);
|
||||
cancelIntent.setAction(ACTION_CANCELBOLUS);
|
||||
PendingIntent cancelPendingIntent = PendingIntent.getService(this, 0, cancelIntent, 0);;
|
||||
|
||||
long[] vibratePattern;
|
||||
boolean vibreate = PreferenceManager
|
||||
.getDefaultSharedPreferences(this).getBoolean("vibrateOnBolus", true);
|
||||
if(vibreate){
|
||||
vibratePattern = new long[]{0, 50, 1000};
|
||||
boolean vibreate = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("vibrateOnBolus", true);
|
||||
if (vibreate) {
|
||||
vibratePattern = new long[] { 0, 50, 1000 };
|
||||
} else {
|
||||
vibratePattern = new long[]{0, 1, 1000};
|
||||
vibratePattern = new long[] { 0, 1, 1000 };
|
||||
}
|
||||
|
||||
NotificationCompat.Builder notificationBuilder =
|
||||
new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_icon)
|
||||
.setContentTitle("Bolus Progress")
|
||||
.setContentText(progresspercent + "% - " + progresstatus)
|
||||
.setContentIntent(cancelPendingIntent)
|
||||
.setPriority(NotificationCompat.PRIORITY_MAX)
|
||||
.setVibrate(vibratePattern)
|
||||
.addAction(R.drawable.ic_cancel, "CANCEL BOLUS", cancelPendingIntent);
|
||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_icon).setContentTitle("Bolus Progress")
|
||||
.setContentText(progresspercent + "% - " + progresstatus).setContentIntent(cancelPendingIntent)
|
||||
.setPriority(NotificationCompat.PRIORITY_MAX).setVibrate(vibratePattern)
|
||||
.addAction(R.drawable.ic_cancel, "CANCEL BOLUS", cancelPendingIntent);
|
||||
|
||||
NotificationManagerCompat notificationManager =
|
||||
NotificationManagerCompat.from(this);
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
|
||||
|
||||
if(confirmThread != null){
|
||||
if (confirmThread != null) {
|
||||
confirmThread.invalidate();
|
||||
}
|
||||
notificationManager.notify(BOLUS_PROGRESS_NOTIF_ID, notificationBuilder.build());
|
||||
notificationManager.cancel(CONFIRM_NOTIF_ID); // multiple watch setup
|
||||
|
||||
|
||||
if (progresspercent == 100){
|
||||
if (progresspercent == 100) {
|
||||
scheduleDismissBolusprogress(5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void showConfirmationDialog(String title, String message, String actionstring) {
|
||||
|
||||
Intent intent = new Intent(this, AcceptActivity.class);
|
||||
|
@ -416,49 +628,54 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
startActivity(intent);
|
||||
}
|
||||
|
||||
|
||||
private void scheduleDismissBolusprogress(final int seconds) {
|
||||
if(confirmThread != null){
|
||||
if (confirmThread != null) {
|
||||
confirmThread.invalidate();
|
||||
}
|
||||
bolusprogressThread = new DismissThread(BOLUS_PROGRESS_NOTIF_ID, seconds);
|
||||
bolusprogressThread.start();
|
||||
}
|
||||
|
||||
private class DismissThread extends Thread {
|
||||
|
||||
|
||||
private class DismissThread extends Thread{
|
||||
private final int notificationID;
|
||||
private final int seconds;
|
||||
private boolean valid = true;
|
||||
|
||||
DismissThread(int notificationID, int seconds){
|
||||
|
||||
DismissThread(int notificationID, int seconds) {
|
||||
this.notificationID = notificationID;
|
||||
this.seconds = seconds;
|
||||
}
|
||||
|
||||
public synchronized void invalidate(){
|
||||
|
||||
public synchronized void invalidate() {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
SystemClock.sleep(seconds * 1000);
|
||||
synchronized (this) {
|
||||
if(valid) {
|
||||
NotificationManagerCompat notificationManager =
|
||||
NotificationManagerCompat.from(ListenerService.this);
|
||||
if (valid) {
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat
|
||||
.from(ListenerService.this);
|
||||
notificationManager.cancel(notificationID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void requestData(Context context) {
|
||||
Intent intent = new Intent(context, ListenerService.class);
|
||||
intent.setAction(ACTION_RESEND);
|
||||
context.startService(intent);
|
||||
}
|
||||
|
||||
|
||||
public static void initiateAction(Context context, String actionstring) {
|
||||
Intent intent = new Intent(context, ListenerService.class);
|
||||
intent.putExtra("actionstring", actionstring);
|
||||
|
@ -466,6 +683,7 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
context.startService(intent);
|
||||
}
|
||||
|
||||
|
||||
public static void confirmAction(Context context, String actionstring) {
|
||||
Intent intent = new Intent(context, ListenerService.class);
|
||||
intent.putExtra("actionstring", actionstring);
|
||||
|
@ -478,29 +696,71 @@ public class ListenerService extends WearableListenerService implements GoogleAp
|
|||
context.startService(intent);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onConnected(Bundle bundle) {
|
||||
// Log.d(TAG, logPrefix + "onConnected call requestData");
|
||||
|
||||
CapabilityApi.CapabilityListener capabilityListener = new CapabilityApi.CapabilityListener() {
|
||||
|
||||
@Override
|
||||
public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
|
||||
updatePhoneSyncBgsCapability(capabilityInfo);
|
||||
Log.d(TAG, logPrefix + "onConnected onCapabilityChanged mPhoneNodeID:" + mPhoneNodeId
|
||||
+ ", Capability: " + capabilityInfo);
|
||||
}
|
||||
};
|
||||
|
||||
Wearable.CapabilityApi.addCapabilityListener(googleApiClient, capabilityListener, CAPABILITY_PHONE_APP);
|
||||
|
||||
Wearable.ChannelApi.addListener(googleApiClient, this);
|
||||
requestData();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onConnectionSuspended(int i) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed(ConnectionResult connectionResult) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void setLocalNodeName() {
|
||||
forceGoogleApiConnect();
|
||||
PendingResult<NodeApi.GetLocalNodeResult> result = Wearable.NodeApi.getLocalNode(googleApiClient);
|
||||
result.setResultCallback(new ResultCallback<NodeApi.GetLocalNodeResult>() {
|
||||
|
||||
@Override
|
||||
public void onResult(NodeApi.GetLocalNodeResult getLocalNodeResult) {
|
||||
if (!getLocalNodeResult.getStatus().isSuccess()) {
|
||||
Log.e(TAG, "ERROR: failed to getLocalNode Status="
|
||||
+ getLocalNodeResult.getStatus().getStatusMessage());
|
||||
} else {
|
||||
Log.d(TAG, "getLocalNode Status=: " + getLocalNodeResult.getStatus().getStatusMessage());
|
||||
Node getnode = getLocalNodeResult.getNode();
|
||||
localnode = getnode != null ? getnode.getDisplayName() + "|" + getnode.getId() : "";
|
||||
Log.d(TAG, "setLocalNodeName. localnode=" + localnode);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (googleApiClient != null && googleApiClient.isConnected()) {
|
||||
googleApiClient.disconnect();
|
||||
}
|
||||
|
||||
if (googleApiClient != null) {
|
||||
Wearable.MessageApi.removeListener(googleApiClient, this);
|
||||
Wearable.ChannelApi.removeListener(googleApiClient, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package info.nightscout.androidaps.interaction.utils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by andy on 3/5/19.
|
||||
*/
|
||||
|
||||
public class WearUtil {
|
||||
|
||||
public static String dateTimeText(long timeInMs) {
|
||||
Date d = new Date(timeInMs);
|
||||
return "" + d.getDay() + "." + d.getMonth() + "." + d.getYear() + " " + d.getHours() + ":" + d.getMinutes()
|
||||
+ ":" + d.getSeconds();
|
||||
}
|
||||
|
||||
}
|
18
wear/src/main/res/values/wear.xml
Normal file
18
wear/src/main/res/values/wear.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2015 Google Inc. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string-array name="android_wear_capabilities">
|
||||
<item>phone_app_sync_bgs</item>
|
||||
</string-array>
|
||||
</resources>
|
Loading…
Reference in a new issue