Merge branch 'dev2_dana_combo_only' of github.com:nightscout/AndroidAPS into dev2_dana_combo_only
This commit is contained in:
commit
3b35c01f22
|
@ -111,7 +111,7 @@ android {
|
|||
defaultConfig {
|
||||
multiDexEnabled true
|
||||
versionCode 1500
|
||||
version "2.8.2.1-dev-e3"
|
||||
version "2.8.2.1-dev-e4"
|
||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package info.nightscout.androidaps.data.defaultProfile
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.data.ProfileImplOld
|
||||
import info.nightscout.androidaps.data.PureProfile
|
||||
import info.nightscout.androidaps.extensions.pureProfileFromJson
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.androidaps.data.defaultProfile
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.data.ProfileImplOld
|
||||
import info.nightscout.androidaps.data.PureProfile
|
||||
import info.nightscout.androidaps.extensions.pureProfileFromJson
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||
|
|
|
@ -4,8 +4,6 @@ import android.content.Context;
|
|||
import android.database.DatabaseUtils;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
||||
import com.j256.ormlite.dao.CloseableIterator;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
|
@ -20,9 +18,6 @@ import java.sql.SQLException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -32,7 +27,6 @@ import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
|
|||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
||||
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader;
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
|
@ -51,12 +45,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
@Inject VirtualPumpPlugin virtualPumpPlugin;
|
||||
@Inject OpenHumansUploader openHumansUploader;
|
||||
@Inject ActivePlugin activePlugin;
|
||||
@Inject NSUpload nsUpload;
|
||||
@Inject DateUtil dateUtil;
|
||||
|
||||
public static final String DATABASE_NAME = "AndroidAPSDb";
|
||||
public static final String DATABASE_DANARHISTORY = "DanaRHistory";
|
||||
public static final String DATABASE_DBREQUESTS = "DBRequests";
|
||||
|
||||
private static final int DATABASE_VERSION = 13;
|
||||
|
||||
|
@ -76,10 +67,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
|
||||
try {
|
||||
aapsLogger.info(LTag.DATABASE, "onCreate");
|
||||
TableUtils.createTableIfNotExists(connectionSource, DanaRHistoryRecord.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, TemporaryBasal.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class);
|
||||
|
@ -103,10 +90,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
if (oldVersion < 7) {
|
||||
aapsLogger.info(LTag.DATABASE, "onUpgrade");
|
||||
TableUtils.dropTable(connectionSource, DanaRHistoryRecord.class, true);
|
||||
TableUtils.dropTable(connectionSource, DbRequest.class, true);
|
||||
TableUtils.dropTable(connectionSource, TemporaryBasal.class, true);
|
||||
TableUtils.dropTable(connectionSource, ExtendedBolus.class, true);
|
||||
onCreate(database, connectionSource);
|
||||
} else if (oldVersion < 10) {
|
||||
TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class);
|
||||
|
@ -149,15 +132,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
public void resetDatabases() {
|
||||
try {
|
||||
TableUtils.dropTable(connectionSource, DanaRHistoryRecord.class, true);
|
||||
TableUtils.dropTable(connectionSource, DbRequest.class, true);
|
||||
TableUtils.dropTable(connectionSource, TemporaryBasal.class, true);
|
||||
TableUtils.dropTable(connectionSource, ExtendedBolus.class, true);
|
||||
TableUtils.dropTable(connectionSource, OmnipodHistoryRecord.class, true);
|
||||
TableUtils.createTableIfNotExists(connectionSource, DanaRHistoryRecord.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, TemporaryBasal.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, OmnipodHistoryRecord.class);
|
||||
updateEarliestDataChange(0);
|
||||
} catch (SQLException e) {
|
||||
|
@ -177,22 +152,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
// ------------------ getDao -------------------------------------------
|
||||
|
||||
private Dao<DanaRHistoryRecord, String> getDaoDanaRHistory() throws SQLException {
|
||||
return getDao(DanaRHistoryRecord.class);
|
||||
}
|
||||
|
||||
private Dao<DbRequest, String> getDaoDbRequest() throws SQLException {
|
||||
return getDao(DbRequest.class);
|
||||
}
|
||||
|
||||
private Dao<TemporaryBasal, Long> getDaoTemporaryBasal() throws SQLException {
|
||||
return getDao(TemporaryBasal.class);
|
||||
}
|
||||
|
||||
private Dao<ExtendedBolus, Long> getDaoExtendedBolus() throws SQLException {
|
||||
return getDao(ExtendedBolus.class);
|
||||
}
|
||||
|
||||
private Dao<InsightPumpID, Long> getDaoInsightPumpID() throws SQLException {
|
||||
return getDao(InsightPumpID.class);
|
||||
}
|
||||
|
@ -213,76 +172,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
return getDao(OHQueueItem.class);
|
||||
}
|
||||
|
||||
public long roundDateToSec(long date) {
|
||||
long rounded = date - date % 1000;
|
||||
if (rounded != date)
|
||||
aapsLogger.debug(LTag.DATABASE, "Rounding " + date + " to " + rounded);
|
||||
return rounded;
|
||||
}
|
||||
|
||||
// ------------- DbRequests handling -------------------
|
||||
|
||||
public void create(DbRequest dbr) throws SQLException {
|
||||
getDaoDbRequest().create(dbr);
|
||||
}
|
||||
|
||||
public int delete(DbRequest dbr) {
|
||||
try {
|
||||
return getDaoDbRequest().delete(dbr);
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int deleteDbRequest(String nsClientId) {
|
||||
try {
|
||||
return getDaoDbRequest().deleteById(nsClientId);
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void deleteDbRequestbyMongoId(String action, String id) {
|
||||
try {
|
||||
QueryBuilder<DbRequest, String> queryBuilder = getDaoDbRequest().queryBuilder();
|
||||
// By nsID
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("_id", id).and().eq("action", action);
|
||||
queryBuilder.limit(10L);
|
||||
PreparedQuery<DbRequest> preparedQuery = queryBuilder.prepare();
|
||||
List<DbRequest> dbList = getDaoDbRequest().query(preparedQuery);
|
||||
for (DbRequest r : dbList) delete(r);
|
||||
// By nsClientID
|
||||
where = queryBuilder.where();
|
||||
where.eq("nsClientID", id).and().eq("action", action);
|
||||
queryBuilder.limit(10L);
|
||||
preparedQuery = queryBuilder.prepare();
|
||||
dbList = getDaoDbRequest().query(preparedQuery);
|
||||
for (DbRequest r : dbList) delete(r);
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteAllDbRequests() {
|
||||
try {
|
||||
TableUtils.clearTable(connectionSource, DbRequest.class);
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public CloseableIterator getDbRequestIterator() {
|
||||
try {
|
||||
return getDaoDbRequest().closeableIterator();
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateEarliestDataChange(long newDate) {
|
||||
if (earliestDataChange == null) {
|
||||
earliestDataChange = newDate;
|
||||
|
@ -293,433 +182,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------- DanaRHistory handling --------------------
|
||||
|
||||
public void createOrUpdate(DanaRHistoryRecord record) {
|
||||
try {
|
||||
getDaoDanaRHistory().createOrUpdate(record);
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<DanaRHistoryRecord> getDanaRHistoryRecordsByType(byte type) {
|
||||
List<DanaRHistoryRecord> historyList;
|
||||
try {
|
||||
QueryBuilder<DanaRHistoryRecord, String> queryBuilder = getDaoDanaRHistory().queryBuilder();
|
||||
queryBuilder.orderBy("recordDate", false);
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("recordCode", type);
|
||||
queryBuilder.limit(200L);
|
||||
PreparedQuery<DanaRHistoryRecord> preparedQuery = queryBuilder.prepare();
|
||||
historyList = getDaoDanaRHistory().query(preparedQuery);
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
historyList = new ArrayList<>();
|
||||
}
|
||||
return historyList;
|
||||
}
|
||||
|
||||
// ------------ TemporaryBasal handling ---------------
|
||||
|
||||
//return true if new record was created
|
||||
public boolean createOrUpdate(TemporaryBasal tempBasal) {
|
||||
try {
|
||||
TemporaryBasal old;
|
||||
tempBasal.date = roundDateToSec(tempBasal.date);
|
||||
|
||||
if (tempBasal.source == Source.PUMP) {
|
||||
// check for changed from pump change in NS
|
||||
QueryBuilder<TemporaryBasal, Long> queryBuilder = getDaoTemporaryBasal().queryBuilder();
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("pumpId", tempBasal.pumpId);
|
||||
PreparedQuery<TemporaryBasal> preparedQuery = queryBuilder.prepare();
|
||||
List<TemporaryBasal> trList = getDaoTemporaryBasal().query(preparedQuery);
|
||||
if (trList.size() > 0) {
|
||||
// do nothing, pump history record cannot be changed
|
||||
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: Already exists from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// search by date (in case its standard record that has become pump record)
|
||||
QueryBuilder<TemporaryBasal, Long> queryBuilder2 = getDaoTemporaryBasal().queryBuilder();
|
||||
Where where2 = queryBuilder2.where();
|
||||
where2.eq("date", tempBasal.date);
|
||||
PreparedQuery<TemporaryBasal> preparedQuery2 = queryBuilder2.prepare();
|
||||
List<TemporaryBasal> trList2 = getDaoTemporaryBasal().query(preparedQuery2);
|
||||
|
||||
if (trList2.size() > 0) {
|
||||
old = trList2.get(0);
|
||||
|
||||
old.copyFromPump(tempBasal);
|
||||
old.source = Source.PUMP;
|
||||
|
||||
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: Updated record with Pump Data : " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
|
||||
getDaoTemporaryBasal().update(old);
|
||||
openHumansUploader.enqueueTemporaryBasal(old);
|
||||
|
||||
updateEarliestDataChange(tempBasal.date);
|
||||
// scheduleTemporaryBasalChange();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
getDaoTemporaryBasal().create(tempBasal);
|
||||
openHumansUploader.enqueueTemporaryBasal(tempBasal);
|
||||
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
updateEarliestDataChange(tempBasal.date);
|
||||
// scheduleTemporaryBasalChange();
|
||||
return true;
|
||||
}
|
||||
if (tempBasal.source == Source.NIGHTSCOUT) {
|
||||
old = getDaoTemporaryBasal().queryForId(tempBasal.date);
|
||||
if (old != null) {
|
||||
if (!old.isAbsolute && tempBasal.isAbsolute) { // converted to absolute by "ns_sync_use_absolute"
|
||||
// so far ignore, do not convert back because it may not be accurate
|
||||
return false;
|
||||
}
|
||||
if (!old.isEqual(tempBasal)) {
|
||||
long oldDate = old.date;
|
||||
getDaoTemporaryBasal().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(tempBasal);
|
||||
getDaoTemporaryBasal().create(old);
|
||||
openHumansUploader.enqueueTemporaryBasal(old);
|
||||
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: Updating record by date from: " + Source.getString(tempBasal.source) + " " + old.toString());
|
||||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
// scheduleTemporaryBasalChange();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// find by NS _id
|
||||
if (tempBasal._id != null) {
|
||||
QueryBuilder<TemporaryBasal, Long> queryBuilder = getDaoTemporaryBasal().queryBuilder();
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("_id", tempBasal._id);
|
||||
PreparedQuery<TemporaryBasal> preparedQuery = queryBuilder.prepare();
|
||||
List<TemporaryBasal> trList = getDaoTemporaryBasal().query(preparedQuery);
|
||||
if (trList.size() > 0) {
|
||||
old = trList.get(0);
|
||||
if (!old.isEqual(tempBasal)) {
|
||||
long oldDate = old.date;
|
||||
getDaoTemporaryBasal().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(tempBasal);
|
||||
getDaoTemporaryBasal().create(old);
|
||||
openHumansUploader.enqueueTemporaryBasal(old);
|
||||
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: Updating record by _id from: " + Source.getString(tempBasal.source) + " " + old.toString());
|
||||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
// scheduleTemporaryBasalChange();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
getDaoTemporaryBasal().create(tempBasal);
|
||||
openHumansUploader.enqueueTemporaryBasal(tempBasal);
|
||||
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
updateEarliestDataChange(tempBasal.date);
|
||||
// scheduleTemporaryBasalChange();
|
||||
return true;
|
||||
}
|
||||
if (tempBasal.source == Source.USER) {
|
||||
getDaoTemporaryBasal().create(tempBasal);
|
||||
openHumansUploader.enqueueTemporaryBasal(tempBasal);
|
||||
aapsLogger.debug(LTag.DATABASE, "TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
updateEarliestDataChange(tempBasal.date);
|
||||
// scheduleTemporaryBasalChange();
|
||||
return true;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void delete(TemporaryBasal tempBasal) {
|
||||
try {
|
||||
getDaoTemporaryBasal().delete(tempBasal);
|
||||
openHumansUploader.enqueueTemporaryBasal(tempBasal, true);
|
||||
updateEarliestDataChange(tempBasal.date);
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
// scheduleTemporaryBasalChange();
|
||||
}
|
||||
|
||||
public List<TemporaryBasal> getTemporaryBasalsDataFromTime(long mills, boolean ascending) {
|
||||
try {
|
||||
List<TemporaryBasal> tempbasals;
|
||||
QueryBuilder<TemporaryBasal, Long> queryBuilder = getDaoTemporaryBasal().queryBuilder();
|
||||
queryBuilder.orderBy("date", ascending);
|
||||
Where where = queryBuilder.where();
|
||||
where.ge("date", mills);
|
||||
PreparedQuery<TemporaryBasal> preparedQuery = queryBuilder.prepare();
|
||||
tempbasals = getDaoTemporaryBasal().query(preparedQuery);
|
||||
return tempbasals;
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return new ArrayList<TemporaryBasal>();
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"_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 TemporaryBasal findTempBasalByPumpId(Long pumpId) {
|
||||
try {
|
||||
QueryBuilder<TemporaryBasal, Long> queryBuilder = null;
|
||||
queryBuilder = getDaoTemporaryBasal().queryBuilder();
|
||||
queryBuilder.orderBy("date", false);
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("pumpId", pumpId);
|
||||
PreparedQuery<TemporaryBasal> preparedQuery = queryBuilder.prepare();
|
||||
List<TemporaryBasal> list = getDaoTemporaryBasal().query(preparedQuery);
|
||||
|
||||
if (list.size() > 0)
|
||||
return list.get(0);
|
||||
else
|
||||
return null;
|
||||
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// ------------ ExtendedBolus handling ---------------
|
||||
|
||||
public ExtendedBolus getExtendedBolusByPumpId(long pumpId) {
|
||||
try {
|
||||
return getDaoExtendedBolus().queryBuilder()
|
||||
.where().eq("pumpId", pumpId)
|
||||
.queryForFirst();
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void delete(ExtendedBolus extendedBolus) {
|
||||
try {
|
||||
getDaoExtendedBolus().delete(extendedBolus);
|
||||
openHumansUploader.enqueueExtendedBolus(extendedBolus, true);
|
||||
updateEarliestDataChange(extendedBolus.date);
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
// scheduleExtendedBolusChange();
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"_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
|
||||
}
|
||||
*/
|
||||
|
||||
// ---------------- ProfileSwitch handling ---------------
|
||||
|
||||
/*
|
||||
public boolean createOrUpdate(ProfileSwitch profileSwitch) {
|
||||
try {
|
||||
ProfileSwitch old;
|
||||
profileSwitch.date = roundDateToSec(profileSwitch.date);
|
||||
|
||||
if (profileSwitch.source == Source.NIGHTSCOUT) {
|
||||
old = getDaoProfileSwitch().queryForId(profileSwitch.date);
|
||||
if (old != null) {
|
||||
if (!old.isEqual(profileSwitch)) {
|
||||
profileSwitch.source = old.source;
|
||||
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);
|
||||
aapsLogger.debug(LTag.DATABASE, "PROFILESWITCH: Updating record by date from: " + Source.getString(profileSwitch.source) + " " + old.toString());
|
||||
openHumansUploader.enqueueProfileSwitch(profileSwitch);
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// find by NS _id
|
||||
if (profileSwitch._id != null) {
|
||||
QueryBuilder<ProfileSwitch, Long> queryBuilder = getDaoProfileSwitch().queryBuilder();
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("_id", profileSwitch._id);
|
||||
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
|
||||
List<ProfileSwitch> trList = getDaoProfileSwitch().query(preparedQuery);
|
||||
if (trList.size() > 0) {
|
||||
old = trList.get(0);
|
||||
if (!old.isEqual(profileSwitch)) {
|
||||
getDaoProfileSwitch().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(profileSwitch);
|
||||
getDaoProfileSwitch().create(old);
|
||||
aapsLogger.debug(LTag.DATABASE, "PROFILESWITCH: Updating record by _id from: " + Source.getString(profileSwitch.source) + " " + old.toString());
|
||||
openHumansUploader.enqueueProfileSwitch(old);
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// look for already added percentage from NS
|
||||
profileSwitch.profileName = PercentageSplitter.INSTANCE.pureName(profileSwitch.profileName);
|
||||
getDaoProfileSwitch().create(profileSwitch);
|
||||
aapsLogger.debug(LTag.DATABASE, "PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString());
|
||||
openHumansUploader.enqueueProfileSwitch(profileSwitch);
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
if (profileSwitch.source == Source.USER) {
|
||||
getDaoProfileSwitch().create(profileSwitch);
|
||||
aapsLogger.debug(LTag.DATABASE, "PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString());
|
||||
openHumansUploader.enqueueProfileSwitch(profileSwitch);
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void delete(ProfileSwitch profileSwitch) {
|
||||
try {
|
||||
getDaoProfileSwitch().delete(profileSwitch);
|
||||
openHumansUploader.enqueueProfileSwitch(profileSwitch, true);
|
||||
scheduleProfileSwitchChange();
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleProfileSwitchChange() {
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventProfileNeedsUpdate");
|
||||
rxBus.send(new EventReloadProfileSwitchData());
|
||||
rxBus.send(new EventProfileNeedsUpdate());
|
||||
scheduledProfileSwitchEventPost = null;
|
||||
}
|
||||
}
|
||||
// prepare task for execution in 1 sec
|
||||
// cancel waiting task to prevent sending multiple posts
|
||||
if (scheduledProfileSwitchEventPost != null)
|
||||
scheduledProfileSwitchEventPost.cancel(false);
|
||||
Runnable task = new PostRunnable();
|
||||
final int sec = 1;
|
||||
scheduledProfileSwitchEventPost = profileSwitchEventWorker.schedule(task, sec, TimeUnit.SECONDS);
|
||||
|
||||
}
|
||||
*/
|
||||
/*
|
||||
{
|
||||
"_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 {
|
||||
ProfileSwitch profileSwitch = new ProfileSwitch(StaticInjector.Companion.getInstance());
|
||||
profileSwitch.date = trJson.getLong("mills");
|
||||
if (trJson.has("duration"))
|
||||
profileSwitch.durationInMinutes = trJson.getInt("duration");
|
||||
profileSwitch._id = trJson.getString("_id");
|
||||
profileSwitch.profileName = trJson.getString("profile");
|
||||
profileSwitch.isCPP = trJson.has("CircadianPercentageProfile");
|
||||
profileSwitch.source = Source.NIGHTSCOUT;
|
||||
if (trJson.has("timeshift"))
|
||||
profileSwitch.timeshift = trJson.getInt("timeshift");
|
||||
if (trJson.has("percentage"))
|
||||
profileSwitch.percentage = trJson.getInt("percentage");
|
||||
if (trJson.has("profileJson"))
|
||||
profileSwitch.profileJson = trJson.getString("profileJson");
|
||||
else {
|
||||
ProfileSource profileSource = activePlugin.getActiveProfileSource();
|
||||
ProfileStore store = profileSource.getProfile();
|
||||
if (store != null) {
|
||||
PureProfile profile = store.getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null) {
|
||||
profileSwitch.profileJson = profile.getJsonObject().toString();
|
||||
aapsLogger.debug(LTag.DATABASE, "Profile switch prefilled with JSON from local store");
|
||||
// Update data in NS
|
||||
nsUpload.updateProfileSwitch(profileSwitch, dateUtil);
|
||||
} else {
|
||||
aapsLogger.debug(LTag.DATABASE, "JSON for profile switch doesn't exist. Ignoring: " + trJson.toString());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
aapsLogger.debug(LTag.DATABASE, "Store for profile switch doesn't exist. Ignoring: " + trJson.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (trJson.has("profilePlugin"))
|
||||
profileSwitch.profilePlugin = trJson.getString("profilePlugin");
|
||||
createOrUpdate(profileSwitch);
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception: " + trJson.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteProfileSwitchById(String _id) {
|
||||
ProfileSwitch stored = findProfileSwitchById(_id);
|
||||
if (stored != null) {
|
||||
aapsLogger.debug(LTag.DATABASE, "PROFILESWITCH: Removing ProfileSwitch record from database: " + stored.toString());
|
||||
delete(stored);
|
||||
scheduleProfileSwitchChange();
|
||||
}
|
||||
}
|
||||
|
||||
public ProfileSwitch findProfileSwitchById(String _id) {
|
||||
try {
|
||||
QueryBuilder<ProfileSwitch, Long> queryBuilder = getDaoProfileSwitch().queryBuilder();
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("_id", _id);
|
||||
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
|
||||
List<ProfileSwitch> list = getDaoProfileSwitch().query(preparedQuery);
|
||||
|
||||
if (list.size() == 1) {
|
||||
return list.get(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
// ---------------- Insight history handling ---------------
|
||||
|
||||
public void createOrUpdate(InsightHistoryOffset offset) {
|
||||
|
@ -924,14 +386,4 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public long getCountOfAllRows() {
|
||||
try {
|
||||
return getDaoExtendedBolus().countOf()
|
||||
+ getDaoTemporaryBasal().countOf();
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ import androidx.annotation.Nullable;
|
|||
|
||||
import com.j256.ormlite.dao.CloseableIterator;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -23,61 +21,24 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
|
|||
@Inject DatabaseHelperProvider() {
|
||||
}
|
||||
|
||||
@Override public void createOrUpdate(@NonNull DanaRHistoryRecord record) {
|
||||
MainApp.Companion.getDbHelper().createOrUpdate(record);
|
||||
}
|
||||
|
||||
@Override public void createOrUpdate(@NonNull OmnipodHistoryRecord record) {
|
||||
MainApp.Companion.getDbHelper().createOrUpdate(record);
|
||||
}
|
||||
|
||||
@NonNull @Override public List<DanaRHistoryRecord> getDanaRHistoryRecordsByType(byte type) {
|
||||
return MainApp.Companion.getDbHelper().getDanaRHistoryRecordsByType(type);
|
||||
}
|
||||
|
||||
@Override public long size(@NonNull String table) {
|
||||
return MainApp.Companion.getDbHelper().size(table);
|
||||
}
|
||||
|
||||
@Override public void create(@NonNull DbRequest record) {
|
||||
try {
|
||||
MainApp.Companion.getDbHelper().create(record);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void deleteAllDbRequests() {
|
||||
MainApp.Companion.getDbHelper().deleteAllDbRequests();
|
||||
}
|
||||
|
||||
@Override public int deleteDbRequest(@NonNull String id) {
|
||||
return MainApp.Companion.getDbHelper().deleteDbRequest(id);
|
||||
}
|
||||
|
||||
@Override public void deleteDbRequestbyMongoId(@NonNull String action, @NonNull String _id) {
|
||||
MainApp.Companion.getDbHelper().deleteDbRequestbyMongoId(action, _id);
|
||||
}
|
||||
|
||||
@NonNull @Override public CloseableIterator<DbRequest> getDbRequestIterator() {
|
||||
return MainApp.Companion.getDbHelper().getDbRequestIterator();
|
||||
}
|
||||
|
||||
@Override public long roundDateToSec(long date) {
|
||||
return MainApp.Companion.getDbHelper().roundDateToSec(date);
|
||||
}
|
||||
|
||||
@Override public boolean createOrUpdate(@NonNull TemporaryBasal tempBasal) {
|
||||
return MainApp.Companion.getDbHelper().createOrUpdate(tempBasal);
|
||||
// return MainApp.Companion.getDbHelper().createOrUpdate(tempBasal);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable @Override public TemporaryBasal findTempBasalByPumpId(long id) {
|
||||
return MainApp.Companion.getDbHelper().findTempBasalByPumpId(id);
|
||||
// return MainApp.Companion.getDbHelper().findTempBasalByPumpId(id);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@NonNull @Override public List<TemporaryBasal> getTemporaryBasalsDataFromTime(long mills, boolean ascending) {
|
||||
return MainApp.Companion.getDbHelper().getTemporaryBasalsDataFromTime(mills, ascending);
|
||||
// return MainApp.Companion.getDbHelper().getTemporaryBasalsDataFromTime(mills, ascending);
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull @Override public List<OmnipodHistoryRecord> getAllOmnipodHistoryRecordsFromTimestamp(long timestamp, boolean ascending) {
|
||||
|
@ -101,11 +62,12 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
|
|||
}
|
||||
|
||||
@Override public void delete(@NonNull ExtendedBolus extendedBolus) {
|
||||
MainApp.Companion.getDbHelper().delete(extendedBolus);
|
||||
// MainApp.Companion.getDbHelper().delete(extendedBolus);
|
||||
}
|
||||
|
||||
@Nullable @Override public ExtendedBolus getExtendedBolusByPumpId(long pumpId) {
|
||||
return MainApp.Companion.getDbHelper().getExtendedBolusByPumpId(pumpId);
|
||||
// return MainApp.Companion.getDbHelper().getExtendedBolusByPumpId(pumpId);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable @Override public InsightBolusID getInsightBolusID(@NonNull String pumpSerial, int bolusID, long timestamp) {
|
||||
|
@ -140,10 +102,6 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
|
|||
MainApp.Companion.getDbHelper().clearOpenHumansQueue();
|
||||
}
|
||||
|
||||
@Override public long getCountOfAllRows() {
|
||||
return MainApp.Companion.getDbHelper().getCountOfAllRows();
|
||||
}
|
||||
|
||||
@Override public void removeAllOHQueueItemsWithIdSmallerThan(long id) {
|
||||
MainApp.Companion.getDbHelper().removeAllOHQueueItemsWithIdSmallerThan(id);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import dagger.android.AndroidInjector
|
|||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.automation.di.AutomationModule
|
||||
import info.nightscout.androidaps.combo.di.ComboModule
|
||||
import info.nightscout.androidaps.dana.di.DanaHistoryModule
|
||||
import info.nightscout.androidaps.di.CoreModule
|
||||
import info.nightscout.androidaps.dana.di.DanaModule
|
||||
import info.nightscout.androidaps.danar.di.DanaRModule
|
||||
|
@ -45,6 +46,7 @@ import javax.inject.Singleton
|
|||
UIModule::class,
|
||||
CoreModule::class,
|
||||
DanaModule::class,
|
||||
DanaHistoryModule::class,
|
||||
DanaRModule::class,
|
||||
DanaRSModule::class,
|
||||
ComboModule::class,
|
||||
|
|
|
@ -6,32 +6,34 @@ import dagger.Lazy
|
|||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.db.DatabaseHelperProvider
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.PluginStore
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefsImpl
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.DataSyncSelectorImplementation
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.PumpSyncImplementation
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.queue.CommandQueue
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl
|
||||
import info.nightscout.androidaps.utils.buildHelper.ConfigImpl
|
||||
import info.nightscout.androidaps.utils.resources.IconsProviderImplementation
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.rx.DefaultAapsSchedulers
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import info.nightscout.androidaps.utils.storage.FileStorage
|
||||
import info.nightscout.androidaps.utils.storage.Storage
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Suppress("unused")
|
||||
@Module(includes = [
|
||||
AppModule.AppBindings::class
|
||||
|
@ -64,13 +66,9 @@ open class AppModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesUploadQueue(
|
||||
aapsLogger: AAPSLogger,
|
||||
databaseHelper: DatabaseHelperInterface,
|
||||
context: Context,
|
||||
sp: SP,
|
||||
rxBus: RxBusWrapper
|
||||
): UploadQueueAdminInterface = UploadQueue(aapsLogger, databaseHelper, context, sp, rxBus)
|
||||
fun provideProfileFunction(aapsLogger: AAPSLogger, sp: SP, resourceHelper: ResourceHelper, activePlugin: ActivePlugin, repository: AppRepository, dateUtil: DateUtil): ProfileFunction {
|
||||
return ProfileFunctionImplementation(aapsLogger, sp, resourceHelper, activePlugin, repository, dateUtil)
|
||||
}
|
||||
|
||||
@Module
|
||||
interface AppBindings {
|
||||
|
@ -88,7 +86,6 @@ open class AppModule {
|
|||
@Binds fun bindLoopInterface(loopPlugin: LoopPlugin): LoopInterface
|
||||
@Binds fun bindIobCobCalculatorInterface(iobCobCalculatorPlugin: IobCobCalculatorPlugin): IobCobCalculator
|
||||
@Binds fun bindSmsCommunicatorInterface(smsCommunicatorPlugin: SmsCommunicatorPlugin): SmsCommunicator
|
||||
@Binds fun bindUploadQueueAdminInterfaceToUploadQueue(uploadQueueAdminInterface: UploadQueueAdminInterface) : UploadQueueInterface
|
||||
@Binds fun bindDataSyncSelector(dataSyncSelectorImplementation: DataSyncSelectorImplementation): DataSyncSelector
|
||||
@Binds fun bindPumpSync(pumpSyncImplementation: PumpSyncImplementation): PumpSync
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ import info.nightscout.androidaps.plugins.general.tidepool.TidepoolFragment
|
|||
import info.nightscout.androidaps.plugins.general.wear.WearFragment
|
||||
import info.nightscout.androidaps.plugins.insulin.InsulinFragment
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
|
||||
import info.nightscout.androidaps.plugins.source.BGSourceFragment
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsFragment
|
||||
|
@ -46,8 +45,7 @@ abstract class FragmentsModule {
|
|||
@ContributesAndroidInjector abstract fun contributesAutomationFragment(): AutomationFragment
|
||||
@ContributesAndroidInjector abstract fun contributesBGSourceFragment(): BGSourceFragment
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment
|
||||
@ContributesAndroidInjector abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesFoodFragment(): FoodFragment
|
||||
@ContributesAndroidInjector abstract fun contributesInsulinFragment(): InsulinFragment
|
||||
|
@ -58,10 +56,8 @@ abstract class FragmentsModule {
|
|||
@ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment
|
||||
@ContributesAndroidInjector abstract fun contributesLoopFragment(): LoopFragment
|
||||
@ContributesAndroidInjector abstract fun contributesMaintenanceFragment(): MaintenanceFragment
|
||||
@ContributesAndroidInjector abstract fun contributesNSProfileFragment(): NSProfileFragment
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientFragment(): NSClientFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
|
||||
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
|
||||
@ContributesAndroidInjector abstract fun contributesWearFragment(): WearFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment
|
||||
|
@ -85,8 +81,7 @@ abstract class FragmentsModule {
|
|||
@ContributesAndroidInjector abstract fun contributesEditEventDialog(): EditEventDialog
|
||||
@ContributesAndroidInjector abstract fun contributesEditTriggerDialog(): EditTriggerDialog
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesEditQuickWizardDialog(): EditQuickWizardDialog
|
||||
@ContributesAndroidInjector abstract fun contributesEditQuickWizardDialog(): EditQuickWizardDialog
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesExtendedBolusDialog(): ExtendedBolusDialog
|
||||
@ContributesAndroidInjector abstract fun contributesFillDialog(): FillDialog
|
||||
|
@ -102,8 +97,7 @@ abstract class FragmentsModule {
|
|||
@ContributesAndroidInjector abstract fun contributesWizardDialog(): WizardDialog
|
||||
@ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesExchangeAuthTokenDialot(): OpenHumansLoginActivity.ExchangeAuthTokenDialog
|
||||
@ContributesAndroidInjector abstract fun contributesExchangeAuthTokenDialog(): OpenHumansLoginActivity.ExchangeAuthTokenDialog
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesPasswordCheck(): PasswordCheck
|
||||
}
|
|
@ -37,7 +37,6 @@ import info.nightscout.androidaps.plugins.insulin.InsulinOrefRapidActingPlugin
|
|||
import info.nightscout.androidaps.plugins.insulin.InsulinOrefUltraRapidActingPlugin
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.mdi.MDIPlugin
|
||||
|
@ -192,12 +191,6 @@ abstract class PluginsModule {
|
|||
@IntKey(220)
|
||||
abstract fun bindOpenAPSSMBPlugin(plugin: OpenAPSSMBPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
@IntKey(230)
|
||||
abstract fun bindNSProfilePlugin(plugin: NSProfilePlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@NotNSClient
|
||||
@IntoMap
|
||||
|
|
|
@ -9,7 +9,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSClientMbgWorker
|
|||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientRemoveWorker
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientUpdateRemoveAckWorker
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.source.*
|
||||
|
||||
@Module
|
||||
|
@ -24,7 +24,7 @@ abstract class WorkersModule {
|
|||
@ContributesAndroidInjector abstract fun contributesTomatoWorker(): TomatoPlugin.TomatoWorker
|
||||
@ContributesAndroidInjector abstract fun contributesEversenseWorker(): EversensePlugin.EversenseWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientSourceWorker(): NSClientSourcePlugin.NSClientSourceWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSProfileWorker(): NSProfilePlugin.NSProfileWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSProfileWorker(): LocalProfilePlugin.NSProfileWorker
|
||||
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorWorker(): SmsCommunicatorPlugin.SmsCommunicatorWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientWorker(): NSClientAddUpdateWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientAddAckWorker(): NSClientAddAckWorker
|
||||
|
|
|
@ -403,7 +403,7 @@ open class LoopPlugin @Inject constructor(
|
|||
val waiting = PumpEnactResult(injector)
|
||||
waiting.queued = true
|
||||
if (resultAfterConstraints.tempBasalRequested) lastRun.tbrSetByPump = waiting
|
||||
if (resultAfterConstraints.bolusRequested) lastRun.smbSetByPump = waiting
|
||||
if (resultAfterConstraints.bolusRequested()) lastRun.smbSetByPump = waiting
|
||||
rxBus.send(EventLoopUpdateGui())
|
||||
fabricPrivacy.logCustom("APSRequest")
|
||||
applyTBRRequest(resultAfterConstraints, profile, object : Callback() {
|
||||
|
@ -600,7 +600,7 @@ open class LoopPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
private fun applySMBRequest(request: APSResult, callback: Callback?) {
|
||||
if (!request.bolusRequested) {
|
||||
if (!request.bolusRequested()) {
|
||||
return
|
||||
}
|
||||
val pump = activePlugin.activePump
|
||||
|
|
|
@ -40,7 +40,6 @@ class DetermineBasalResultAMA private constructor(injector: HasAndroidInjector)
|
|||
tempBasalRequested = false
|
||||
}
|
||||
}
|
||||
bolusRequested = false
|
||||
}
|
||||
|
||||
override fun newAndClone(injector: HasAndroidInjector): DetermineBasalResultAMA {
|
||||
|
|
|
@ -35,7 +35,6 @@ class DetermineBasalResultSMB private constructor(injector: HasAndroidInjector)
|
|||
duration = -1
|
||||
}
|
||||
if (result.has("units")) {
|
||||
bolusRequested = true
|
||||
smb = result.getDouble("units")
|
||||
} else {
|
||||
smb = 0.0
|
||||
|
|
|
@ -28,7 +28,7 @@ class Objective3 @Inject constructor(injector: HasAndroidInjector) : Objective(i
|
|||
}
|
||||
|
||||
override fun specialActionEnabled(): Boolean =
|
||||
NSClientService.isConnected && NSClientService.hasWriteAuth
|
||||
nsClientPlugin.nsClientService?.isConnected == true && nsClientPlugin.nsClientService?.hasWriteAuth == true
|
||||
|
||||
override fun specialAction(activity: FragmentActivity, input: String) {
|
||||
objectivesPlugin.completeObjectives(activity, input)
|
||||
|
|
|
@ -7,13 +7,13 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.dana.database.DanaHistoryDatabase
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.databinding.MaintenanceFragmentBinding
|
||||
import info.nightscout.androidaps.events.EventNewBG
|
||||
import info.nightscout.androidaps.interfaces.DataSyncSelector
|
||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
||||
import info.nightscout.androidaps.interfaces.ImportExportPrefs
|
||||
import info.nightscout.androidaps.interfaces.PumpSync
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
|
@ -38,7 +38,7 @@ class MaintenanceFragment : DaggerFragment() {
|
|||
@Inject lateinit var importExportPrefs: ImportExportPrefs
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var databaseHelper: DatabaseHelperInterface
|
||||
@Inject lateinit var danaHistoryDatabase: DanaHistoryDatabase
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var pumpSync: PumpSync
|
||||
|
@ -68,8 +68,8 @@ class MaintenanceFragment : DaggerFragment() {
|
|||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.maintenance), resourceHelper.gs(R.string.reset_db_confirm), Runnable {
|
||||
compositeDisposable.add(
|
||||
fromAction {
|
||||
databaseHelper.resetDatabases()
|
||||
repository.clearDatabases()
|
||||
danaHistoryDatabase.clearAllTables()
|
||||
dataSyncSelector.resetToNextFullSync()
|
||||
pumpSync.connectNewPump()
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@ package info.nightscout.androidaps.plugins.general.nsclient
|
|||
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.DeviceStatus
|
||||
import info.nightscout.androidaps.database.entities.*
|
||||
import info.nightscout.androidaps.extensions.toJson
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.DataSyncSelector
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.extensions.toJson
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
|
@ -21,9 +21,27 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
private val profileFunction: ProfileFunction,
|
||||
private val nsClientPlugin: NSClientPlugin,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val appRepository: AppRepository
|
||||
private val appRepository: AppRepository,
|
||||
private val localProfilePlugin: LocalProfilePlugin
|
||||
) : DataSyncSelector {
|
||||
|
||||
override fun doUpload() {
|
||||
if (sp.getBoolean(R.string.key_ns_upload, true)) {
|
||||
processChangedBolusesCompat()
|
||||
processChangedCarbsCompat()
|
||||
processChangedBolusCalculatorResultsCompat()
|
||||
processChangedTemporaryBasalsCompat()
|
||||
processChangedExtendedBolusesCompat()
|
||||
processChangedProfileSwitchesCompat()
|
||||
processChangedGlucoseValuesCompat()
|
||||
processChangedTempTargetsCompat()
|
||||
processChangedFoodsCompat()
|
||||
processChangedTherapyEventsCompat()
|
||||
processChangedDeviceStatusesCompat()
|
||||
processChangedProfileStore()
|
||||
}
|
||||
}
|
||||
|
||||
override fun resetToNextFullSync() {
|
||||
sp.remove(R.string.key_ns_temporary_target_last_synced_id)
|
||||
sp.remove(R.string.key_ns_glucose_value_last_synced_id)
|
||||
|
@ -36,6 +54,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
sp.remove(R.string.key_ns_extended_bolus_last_synced_id)
|
||||
sp.remove(R.string.key_ns_therapy_event_last_synced_id)
|
||||
sp.remove(R.string.key_ns_profile_switch_last_synced_id)
|
||||
sp.remove(R.string.key_ns_profile_store_last_synced_timestamp)
|
||||
}
|
||||
|
||||
override fun confirmLastBolusIdIfGreater(lastSynced: Long) {
|
||||
|
@ -445,4 +464,18 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun confirmLastProfileStore(lastSynced: Long) {
|
||||
sp.putLong(R.string.key_ns_profile_store_last_synced_timestamp, lastSynced)
|
||||
}
|
||||
|
||||
override fun processChangedProfileStore() {
|
||||
val lastSync = sp.getLong(R.string.key_ns_profile_store_last_synced_timestamp, 0)
|
||||
val lastChange = sp.getLong(R.string.key_local_profile_last_change, 0)
|
||||
if (lastChange == 0L) return
|
||||
localProfilePlugin.createProfileStore()
|
||||
val profileJson = localProfilePlugin.profile?.data ?: return
|
||||
if (lastChange > lastSync)
|
||||
nsClientPlugin.nsClientService?.dbAdd("profile", profileJson, DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ class NSClientAddAckWorker(
|
|||
dataSyncSelector.confirmLastCarbsIdIfGreater(pair.updateRecordId)
|
||||
}
|
||||
.blockingGet()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked Carbs" + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked Carbs " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedCarbsCompat()
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ class NSClientAddAckWorker(
|
|||
dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.updateRecordId)
|
||||
}
|
||||
.blockingGet()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked BolusCalculatorResult" + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked BolusCalculatorResult " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedBolusCalculatorResultsCompat()
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ class NSClientAddAckWorker(
|
|||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.updateRecordId)
|
||||
}
|
||||
.blockingGet()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked TemporaryBasal" + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked TemporaryBasal " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTemporaryBasalsCompat()
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ class NSClientAddAckWorker(
|
|||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.updateRecordId)
|
||||
}
|
||||
.blockingGet()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ExtendedBolus" + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ExtendedBolus " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTemporaryBasalsCompat()
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ class NSClientAddAckWorker(
|
|||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.updateRecordId)
|
||||
}
|
||||
.blockingGet()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileSwitch" + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTemporaryBasalsCompat()
|
||||
}
|
||||
|
@ -242,10 +242,15 @@ class NSClientAddAckWorker(
|
|||
dataSyncSelector.confirmLastDeviceStatusIdIfGreater(deviceStatus.id)
|
||||
}
|
||||
.blockingGet()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked DeviceStatus" + deviceStatus.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked DeviceStatus " + deviceStatus.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedDeviceStatusesCompat()
|
||||
}
|
||||
|
||||
is PairProfileStore -> {
|
||||
dataSyncSelector.confirmLastProfileStore(ack.originalObject.timestampSync)
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileStore " + ack.id))
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
|||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.transactions.*
|
||||
import info.nightscout.androidaps.extensions.*
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
|
@ -43,13 +44,11 @@ class NSClientAddUpdateWorker(
|
|||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
|
||||
override fun doWork(): Result {
|
||||
val acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, true) && buildHelper.isEngineeringMode() || config.NSCLIENT
|
||||
if (!acceptNSData) return Result.success()
|
||||
|
||||
val treatments = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
|
||||
|
@ -73,62 +72,66 @@ class NSClientAddUpdateWorker(
|
|||
if (mills > latestDateInReceivedData) latestDateInReceivedData = mills
|
||||
|
||||
if (insulin > 0) {
|
||||
bolusFromJson(json)?.let { bolus ->
|
||||
repository.runTransactionForResult(SyncNsBolusTransaction(bolus, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving bolus", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bolus $it")
|
||||
if (sp.getBoolean(R.string.key_ns_receive_insulin, false) && buildHelper.isEngineeringMode() || config.NSCLIENT) {
|
||||
bolusFromJson(json)?.let { bolus ->
|
||||
repository.runTransactionForResult(SyncNsBolusTransaction(bolus, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving bolus", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.BOLUS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bolus $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.BOLUS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId bolus $it")
|
||||
}
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId bolus $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing bolus json $json")
|
||||
} ?: aapsLogger.error("Error parsing bolus json $json")
|
||||
}
|
||||
}
|
||||
if (carbs > 0) {
|
||||
carbsFromJson(json)?.let { carb ->
|
||||
repository.runTransactionForResult(SyncNsCarbsTransaction(carb, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.CARBS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Gram(it.amount.toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it")
|
||||
if (sp.getBoolean(R.string.key_ns_receive_carbs, false) && buildHelper.isEngineeringMode() || config.NSCLIENT) {
|
||||
carbsFromJson(json)?.let { carb ->
|
||||
repository.runTransactionForResult(SyncNsCarbsTransaction(carb, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.CARBS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Gram(it.amount.toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.CARBS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Gram(it.amount.toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.CARBS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Gram(it.amount.toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId carbs $it")
|
||||
}
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId carbs $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing bolus json $json")
|
||||
} ?: aapsLogger.error("Error parsing bolus json $json")
|
||||
}
|
||||
}
|
||||
// Convert back emulated TBR -> EB
|
||||
if (eventType == TherapyEvent.Type.TEMPORARY_BASAL.text && json.has("extendedEmulated")) {
|
||||
|
@ -140,46 +143,48 @@ class NSClientAddUpdateWorker(
|
|||
when {
|
||||
insulin > 0 || carbs > 0 -> Any()
|
||||
eventType == TherapyEvent.Type.TEMPORARY_TARGET.text ->
|
||||
temporaryTargetFromJson(json)?.let { temporaryTarget ->
|
||||
repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach { tt ->
|
||||
uel.log(Action.TT, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.fromGlucoseUnit(tt.lowTarget, Constants.MGDL),
|
||||
ValueWithUnit.fromGlucoseUnit(tt.highTarget, Constants.MGDL).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryTarget $tt")
|
||||
if (sp.getBoolean(R.string.key_ns_receive_temp_target, false) && buildHelper.isEngineeringMode() || config.NSCLIENT) {
|
||||
temporaryTargetFromJson(json)?.let { temporaryTarget ->
|
||||
repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach { tt ->
|
||||
uel.log(Action.TT_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.Mgdl(tt.lowTarget),
|
||||
ValueWithUnit.Mgdl(tt.highTarget).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryTarget $tt")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach { tt ->
|
||||
uel.log(Action.TT, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.fromGlucoseUnit(tt.lowTarget, Constants.MGDL),
|
||||
ValueWithUnit.fromGlucoseUnit(tt.highTarget, Constants.MGDL).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryTarget $tt")
|
||||
}
|
||||
result.invalidated.forEach { tt ->
|
||||
uel.log(Action.TT_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.Mgdl(tt.lowTarget),
|
||||
ValueWithUnit.Mgdl(tt.highTarget).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryTarget $tt")
|
||||
}
|
||||
result.ended.forEach { tt ->
|
||||
uel.log(Action.CANCEL_TT, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.Mgdl(tt.lowTarget),
|
||||
ValueWithUnit.Mgdl(tt.highTarget).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated TemporaryTarget $tt")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryTarget $it")
|
||||
}
|
||||
}
|
||||
result.ended.forEach { tt ->
|
||||
uel.log(Action.CANCEL_TT, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.Mgdl(tt.lowTarget),
|
||||
ValueWithUnit.Mgdl(tt.highTarget).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated TemporaryTarget $tt")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryTarget $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing TT json $json")
|
||||
} ?: aapsLogger.error("Error parsing TT json $json")
|
||||
}
|
||||
eventType == TherapyEvent.Type.CANNULA_CHANGE.text ||
|
||||
eventType == TherapyEvent.Type.INSULIN_CHANGE.text ||
|
||||
eventType == TherapyEvent.Type.SENSOR_CHANGE.text ||
|
||||
|
@ -190,158 +195,167 @@ class NSClientAddUpdateWorker(
|
|||
eventType == TherapyEvent.Type.EXERCISE.text ||
|
||||
eventType == TherapyEvent.Type.APS_OFFLINE.text ||
|
||||
eventType == TherapyEvent.Type.PUMP_BATTERY_CHANGE.text ->
|
||||
therapyEventFromJson(json)?.let { therapyEvent ->
|
||||
repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEvent, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
val action = when (eventType) {
|
||||
TherapyEvent.Type.CANNULA_CHANGE.text -> Action.SITE_CHANGE
|
||||
TherapyEvent.Type.INSULIN_CHANGE.text -> Action.RESERVOIR_CHANGE
|
||||
else -> Action.CAREPORTAL
|
||||
if (sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT) {
|
||||
therapyEventFromJson(json)?.let { therapyEvent ->
|
||||
repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEvent, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.inserted.forEach {
|
||||
uel.log(action, Sources.NSClient,
|
||||
it.note ?: "",
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.TherapyEventType(it.type)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TherapyEvent $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
val action = when (eventType) {
|
||||
TherapyEvent.Type.CANNULA_CHANGE.text -> Action.SITE_CHANGE
|
||||
TherapyEvent.Type.INSULIN_CHANGE.text -> Action.RESERVOIR_CHANGE
|
||||
else -> Action.CAREPORTAL
|
||||
}
|
||||
result.inserted.forEach {
|
||||
uel.log(action, Sources.NSClient,
|
||||
it.note ?: "",
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.TherapyEventType(it.type)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TherapyEvent $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.CAREPORTAL_REMOVED, Sources.NSClient,
|
||||
it.note ?: "",
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.TherapyEventType(it.type)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TherapyEvent $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TherapyEvent $it")
|
||||
}
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.CAREPORTAL_REMOVED, Sources.NSClient,
|
||||
it.note ?: "",
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.TherapyEventType(it.type)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TherapyEvent $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TherapyEvent $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing TherapyEvent json $json")
|
||||
} ?: aapsLogger.error("Error parsing TherapyEvent json $json")
|
||||
}
|
||||
eventType == TherapyEvent.Type.COMBO_BOLUS.text ->
|
||||
extendedBolusFromJson(json)?.let { extendedBolus ->
|
||||
repository.runTransactionForResult(SyncNsExtendedBolusTransaction(extendedBolus, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving extended bolus", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.EXTENDED_BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted ExtendedBolus $it")
|
||||
if (config.NSCLIENT) {
|
||||
extendedBolusFromJson(json)?.let { extendedBolus ->
|
||||
repository.runTransactionForResult(SyncNsExtendedBolusTransaction(extendedBolus, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving extended bolus", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.EXTENDED_BOLUS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated ExtendedBolus $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.EXTENDED_BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted ExtendedBolus $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.EXTENDED_BOLUS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated ExtendedBolus $it")
|
||||
}
|
||||
result.ended.forEach {
|
||||
uel.log(Action.CANCEL_EXTENDED_BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated ExtendedBolus $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId ExtendedBolus $it")
|
||||
}
|
||||
}
|
||||
result.ended.forEach {
|
||||
uel.log(Action.CANCEL_EXTENDED_BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated ExtendedBolus $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId ExtendedBolus $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing ExtendedBolus json $json")
|
||||
} ?: aapsLogger.error("Error parsing ExtendedBolus json $json")
|
||||
}
|
||||
eventType == TherapyEvent.Type.TEMPORARY_BASAL.text ->
|
||||
temporaryBasalFromJson(json)?.let { temporaryBasal ->
|
||||
repository.runTransactionForResult(SyncNsTemporaryBasalTransaction(temporaryBasal, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary basal", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.TEMP_BASAL, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryBasal $it")
|
||||
if (config.NSCLIENT) {
|
||||
temporaryBasalFromJson(json)?.let { temporaryBasal ->
|
||||
repository.runTransactionForResult(SyncNsTemporaryBasalTransaction(temporaryBasal, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary basal", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.TEMP_BASAL_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryBasal $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.TEMP_BASAL, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryBasal $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.TEMP_BASAL_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryBasal $it")
|
||||
}
|
||||
result.ended.forEach {
|
||||
uel.log(Action.CANCEL_TEMP_BASAL, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Ended TemporaryBasal $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryBasal $it")
|
||||
}
|
||||
}
|
||||
result.ended.forEach {
|
||||
uel.log(Action.CANCEL_TEMP_BASAL, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Ended TemporaryBasal $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryBasal $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json")
|
||||
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json")
|
||||
}
|
||||
eventType == TherapyEvent.Type.PROFILE_SWITCH.text ->
|
||||
profileSwitchFromJson(json, dateUtil)?.let { profileSwitch ->
|
||||
repository.runTransactionForResult(SyncNsProfileSwitchTransaction(profileSwitch, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.PROFILE_SWITCH, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp))
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it")
|
||||
if (sp.getBoolean(R.string.key_ns_receive_profile_switch, false) && buildHelper.isEngineeringMode() || config.NSCLIENT) {
|
||||
profileSwitchFromJson(json, dateUtil, activePlugin)?.let { profileSwitch ->
|
||||
repository.runTransactionForResult(SyncNsProfileSwitchTransaction(profileSwitch, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.PROFILE_SWITCH_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp))
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.PROFILE_SWITCH, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp))
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.PROFILE_SWITCH_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp))
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId ProfileSwitch $it")
|
||||
}
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId ProfileSwitch $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json")
|
||||
} ?: aapsLogger.error("Error parsing ProfileSwitch json $json")
|
||||
}
|
||||
}
|
||||
if (eventType == TherapyEvent.Type.ANNOUNCEMENT.text) {
|
||||
val date = safeGetLong(json, "mills")
|
||||
val now = System.currentTimeMillis()
|
||||
val enteredBy = JsonHelper.safeGetString(json, "enteredBy", "")
|
||||
val notes = JsonHelper.safeGetString(json, "notes", "")
|
||||
if (date > now - 15 * 60 * 1000L && notes.isNotEmpty()
|
||||
&& enteredBy != sp.getString("careportal_enteredby", "AndroidAPS")) {
|
||||
val defaultVal = config.NSCLIENT
|
||||
if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) {
|
||||
val announcement = Notification(Notification.NS_ANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60)
|
||||
rxBus.send(EventNewNotification(announcement))
|
||||
if (sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT)
|
||||
if (eventType == TherapyEvent.Type.ANNOUNCEMENT.text) {
|
||||
val date = safeGetLong(json, "mills")
|
||||
val now = System.currentTimeMillis()
|
||||
val enteredBy = JsonHelper.safeGetString(json, "enteredBy", "")
|
||||
val notes = JsonHelper.safeGetString(json, "notes", "")
|
||||
if (date > now - 15 * 60 * 1000L && notes.isNotEmpty()
|
||||
&& enteredBy != sp.getString("careportal_enteredby", "AndroidAPS")) {
|
||||
val defaultVal = config.NSCLIENT
|
||||
if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) {
|
||||
val announcement = Notification(Notification.NS_ANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60)
|
||||
rxBus.send(EventNewNotification(announcement))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nsClientPlugin.updateLatestDateReceivedIfNewer(latestDateInReceivedData)
|
||||
return ret
|
||||
|
|
|
@ -12,14 +12,11 @@ import info.nightscout.androidaps.database.entities.UserEntry.Action
|
|||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.databinding.NsClientFragmentBinding
|
||||
import info.nightscout.androidaps.interfaces.DataSyncSelector
|
||||
import info.nightscout.androidaps.interfaces.UploadQueueAdminInterface
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.HtmlHelper.fromHtml
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
|
@ -33,7 +30,6 @@ class NSClientFragment : DaggerFragment() {
|
|||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var uploadQueue: UploadQueueAdminInterface
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
|
@ -72,18 +68,6 @@ class NSClientFragment : DaggerFragment() {
|
|||
binding.restart.paintFlags = binding.restart.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.deliverNow.setOnClickListener { nsClientPlugin.resend("GUI") }
|
||||
binding.deliverNow.paintFlags = binding.deliverNow.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.clearQueue.setOnClickListener {
|
||||
context?.let { context ->
|
||||
OKDialog.showConfirmation(context, resourceHelper.gs(R.string.nsclientinternal), resourceHelper.gs(R.string.clearqueueconfirm), Runnable {
|
||||
uel.log(Action.NS_QUEUE_CLEARED, Sources.NSClient)
|
||||
uploadQueue.clearQueue()
|
||||
updateGui()
|
||||
})
|
||||
}
|
||||
}
|
||||
binding.clearQueue.paintFlags = binding.clearQueue.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.showQueue.setOnClickListener { rxBus.send(EventNSClientNewLog("QUEUE", uploadQueue.textList())) }
|
||||
binding.showQueue.paintFlags = binding.showQueue.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.fullSync.setOnClickListener {
|
||||
context?.let { context ->
|
||||
OKDialog.showConfirmation(context, resourceHelper.gs(R.string.nsclientinternal), resourceHelper.gs(R.string.full_sync), Runnable {
|
||||
|
@ -116,7 +100,6 @@ class NSClientFragment : DaggerFragment() {
|
|||
binding.log.text = nsClientPlugin.textLog
|
||||
if (nsClientPlugin.autoscroll) binding.logScrollview.fullScroll(ScrollView.FOCUS_DOWN)
|
||||
binding.url.text = nsClientPlugin.url()
|
||||
binding.queue.text = fromHtml(resourceHelper.gs(R.string.queue) + " <b>" + uploadQueue.size() + "</b>")
|
||||
binding.status.text = nsClientPlugin.status
|
||||
}
|
||||
}
|
|
@ -8,13 +8,13 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.transactions.SyncNsTherapyEventTransaction
|
||||
import info.nightscout.androidaps.extensions.therapyEventFromNsMbg
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg
|
||||
import info.nightscout.androidaps.receivers.DataWorker
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.extensions.therapyEventFromNsMbg
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -33,7 +33,7 @@ class NSClientMbgWorker(
|
|||
override fun doWork(): Result {
|
||||
var ret = Result.success()
|
||||
|
||||
val acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, true) && buildHelper.isEngineeringMode() || config.NSCLIENT
|
||||
val acceptNSData = sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT
|
||||
if (!acceptNSData) return ret
|
||||
|
||||
val mbgArray = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||
|
|
|
@ -1,320 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.nsclient;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.text.Spanned;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.android.HasAndroidInjector;
|
||||
import info.nightscout.androidaps.interfaces.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventChargingState;
|
||||
import info.nightscout.androidaps.events.EventNetworkChange;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientResend;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService;
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||
import info.nightscout.androidaps.utils.HtmlHelper;
|
||||
import info.nightscout.androidaps.utils.ToastUtils;
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers;
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
|
||||
@Singleton
|
||||
public class NSClientPlugin extends PluginBase {
|
||||
private final CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
private final AAPSLogger aapsLogger;
|
||||
private final RxBusWrapper rxBus;
|
||||
private final ResourceHelper resourceHelper;
|
||||
private final Context context;
|
||||
private final AapsSchedulers aapsSchedulers;
|
||||
private final FabricPrivacy fabricPrivacy;
|
||||
private final SP sp;
|
||||
private final NsClientReceiverDelegate nsClientReceiverDelegate;
|
||||
private final Config config;
|
||||
private final BuildHelper buildHelper;
|
||||
|
||||
public Handler handler;
|
||||
|
||||
private final List<EventNSClientNewLog> listLog = new ArrayList<>();
|
||||
Spanned textLog = HtmlHelper.INSTANCE.fromHtml("");
|
||||
|
||||
public boolean paused;
|
||||
boolean autoscroll;
|
||||
|
||||
public String status = "";
|
||||
|
||||
public @Nullable NSClientService nsClientService = null;
|
||||
|
||||
|
||||
@Inject
|
||||
public NSClientPlugin(
|
||||
HasAndroidInjector injector,
|
||||
AAPSLogger aapsLogger,
|
||||
AapsSchedulers aapsSchedulers,
|
||||
RxBusWrapper rxBus,
|
||||
ResourceHelper resourceHelper,
|
||||
Context context,
|
||||
FabricPrivacy fabricPrivacy,
|
||||
SP sp,
|
||||
NsClientReceiverDelegate nsClientReceiverDelegate,
|
||||
Config config,
|
||||
BuildHelper buildHelper
|
||||
) {
|
||||
super(new PluginDescription()
|
||||
.mainType(PluginType.GENERAL)
|
||||
.fragmentClass(NSClientFragment.class.getName())
|
||||
.pluginIcon(R.drawable.ic_nightscout_syncs)
|
||||
.pluginName(R.string.nsclientinternal)
|
||||
.shortName(R.string.nsclientinternal_shortname)
|
||||
.preferencesId(R.xml.pref_nsclientinternal)
|
||||
.description(R.string.description_ns_client),
|
||||
aapsLogger, resourceHelper, injector
|
||||
);
|
||||
|
||||
this.aapsLogger = aapsLogger;
|
||||
this.aapsSchedulers = aapsSchedulers;
|
||||
this.rxBus = rxBus;
|
||||
this.resourceHelper = resourceHelper;
|
||||
this.context = context;
|
||||
this.fabricPrivacy = fabricPrivacy;
|
||||
this.sp = sp;
|
||||
this.nsClientReceiverDelegate = nsClientReceiverDelegate;
|
||||
this.config = config;
|
||||
this.buildHelper = buildHelper;
|
||||
|
||||
if (config.getNSCLIENT()) {
|
||||
getPluginDescription().alwaysEnabled(true).visibleByDefault(true);
|
||||
}
|
||||
if (handler == null) {
|
||||
HandlerThread handlerThread = new HandlerThread(NSClientPlugin.class.getSimpleName() + "Handler");
|
||||
handlerThread.start();
|
||||
handler = new Handler(handlerThread.getLooper());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isAllowed() {
|
||||
return nsClientReceiverDelegate.allowed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
paused = sp.getBoolean(R.string.key_nsclientinternal_paused, false);
|
||||
autoscroll = sp.getBoolean(R.string.key_nsclientinternal_autoscroll, true);
|
||||
|
||||
Intent intent = new Intent(context, NSClientService.class);
|
||||
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||
super.onStart();
|
||||
|
||||
nsClientReceiverDelegate.grabReceiversState();
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventNSClientStatus.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(event -> {
|
||||
status = event.getStatus(resourceHelper);
|
||||
rxBus.send(new EventNSClientUpdateGUI());
|
||||
}, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventNetworkChange.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(nsClientReceiverDelegate::onStatusEvent, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventPreferenceChange.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(nsClientReceiverDelegate::onStatusEvent, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventAppExit.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(event -> {
|
||||
if (nsClientService != null) {
|
||||
context.unbindService(mConnection);
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventNSClientNewLog.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(event -> {
|
||||
addToLog(event);
|
||||
aapsLogger.debug(LTag.NSCLIENT, event.getAction() + " " + event.getLogText());
|
||||
}, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventChargingState.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(nsClientReceiverDelegate::onStatusEvent, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventNSClientResend.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(event -> resend(event.getReason()), fabricPrivacy::logException)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
context.getApplicationContext().unbindService(mConnection);
|
||||
disposable.clear();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preprocessPreferences(@NonNull PreferenceFragmentCompat preferenceFragment) {
|
||||
super.preprocessPreferences(preferenceFragment);
|
||||
|
||||
if (config.getNSCLIENT()) {
|
||||
SwitchPreference key_ns_uploadlocalprofile = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_uploadlocalprofile));
|
||||
if (key_ns_uploadlocalprofile != null) key_ns_uploadlocalprofile.setVisible(false);
|
||||
SwitchPreference key_ns_autobackfill = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_autobackfill));
|
||||
if (key_ns_autobackfill != null) key_ns_autobackfill.setVisible(false);
|
||||
SwitchPreference key_ns_create_announcements_from_errors = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_create_announcements_from_errors));
|
||||
if (key_ns_create_announcements_from_errors != null)
|
||||
key_ns_create_announcements_from_errors.setVisible(false);
|
||||
SwitchPreference key_ns_create_announcements_from_carbs_req = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_create_announcements_from_carbs_req));
|
||||
if (key_ns_create_announcements_from_carbs_req != null)
|
||||
key_ns_create_announcements_from_carbs_req.setVisible(false);
|
||||
SwitchPreference key_ns_upload_only = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_upload_only));
|
||||
if (key_ns_upload_only != null) {
|
||||
key_ns_upload_only.setVisible(false);
|
||||
key_ns_upload_only.setEnabled(false);
|
||||
}
|
||||
SwitchPreference key_ns_sync_use_absolute = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_sync_use_absolute));
|
||||
if (key_ns_sync_use_absolute != null) key_ns_sync_use_absolute.setVisible(false);
|
||||
} else {
|
||||
// APS or pumpControl mode
|
||||
SwitchPreference key_ns_upload_only = preferenceFragment.findPreference(resourceHelper.gs(R.string.key_ns_upload_only));
|
||||
if (key_ns_upload_only != null)
|
||||
key_ns_upload_only.setVisible(buildHelper.isEngineeringMode());
|
||||
}
|
||||
}
|
||||
|
||||
private final ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Service is disconnected");
|
||||
nsClientService = null;
|
||||
}
|
||||
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Service is connected");
|
||||
NSClientService.LocalBinder mLocalBinder = (NSClientService.LocalBinder) service;
|
||||
if (mLocalBinder != null) // is null when running in roboelectric
|
||||
nsClientService = mLocalBinder.getServiceInstance();
|
||||
}
|
||||
};
|
||||
|
||||
synchronized void clearLog() {
|
||||
handler.post(() -> {
|
||||
synchronized (listLog) {
|
||||
listLog.clear();
|
||||
}
|
||||
rxBus.send(new EventNSClientUpdateGUI());
|
||||
});
|
||||
}
|
||||
|
||||
private synchronized void addToLog(final EventNSClientNewLog ev) {
|
||||
handler.post(() -> {
|
||||
synchronized (listLog) {
|
||||
listLog.add(ev);
|
||||
// remove the first line if log is too large
|
||||
if (listLog.size() >= Constants.MAX_LOG_LINES) {
|
||||
listLog.remove(0);
|
||||
}
|
||||
}
|
||||
rxBus.send(new EventNSClientUpdateGUI());
|
||||
});
|
||||
}
|
||||
|
||||
synchronized void updateLog() {
|
||||
try {
|
||||
StringBuilder newTextLog = new StringBuilder();
|
||||
synchronized (listLog) {
|
||||
for (EventNSClientNewLog log : listLog) {
|
||||
newTextLog.append(log.toPreparedHtml());
|
||||
}
|
||||
}
|
||||
textLog = HtmlHelper.INSTANCE.fromHtml(newTextLog.toString());
|
||||
} catch (OutOfMemoryError e) {
|
||||
ToastUtils.showToastInUiThread(context, rxBus, "Out of memory!\nStop using this phone !!!", R.raw.error);
|
||||
}
|
||||
}
|
||||
|
||||
void resend(String reason) {
|
||||
if (nsClientService != null)
|
||||
nsClientService.resend(reason);
|
||||
}
|
||||
|
||||
public void pause(boolean newState) {
|
||||
sp.putBoolean(R.string.key_nsclientinternal_paused, newState);
|
||||
paused = newState;
|
||||
rxBus.send(new EventPreferenceChange(resourceHelper, R.string.key_nsclientinternal_paused));
|
||||
}
|
||||
|
||||
public String url() {
|
||||
return NSClientService.nsURL;
|
||||
}
|
||||
|
||||
public boolean hasWritePermission() {
|
||||
return NSClientService.hasWriteAuth;
|
||||
}
|
||||
|
||||
public void handleClearAlarm(NSAlarm originalAlarm, long silenceTimeInMsec) {
|
||||
|
||||
if (!isEnabled(PluginType.GENERAL)) {
|
||||
return;
|
||||
}
|
||||
if (sp.getBoolean(R.string.key_ns_noupload, false)) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Upload disabled. Message dropped");
|
||||
return;
|
||||
}
|
||||
|
||||
AlarmAck ack = new AlarmAck();
|
||||
ack.level = originalAlarm.level();
|
||||
ack.group = originalAlarm.group();
|
||||
ack.silenceTime = silenceTimeInMsec;
|
||||
|
||||
if (nsClientService != null)
|
||||
nsClientService.sendAlarmAck(ack);
|
||||
}
|
||||
|
||||
public void updateLatestDateReceivedIfNewer(long latestReceived) {
|
||||
if (nsClientService != null && latestReceived > nsClientService.latestDateInReceivedData)
|
||||
nsClientService.latestDateInReceivedData = latestReceived;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
package info.nightscout.androidaps.plugins.general.nsclient
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.IBinder
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreference
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.events.EventAppExit
|
||||
import info.nightscout.androidaps.events.EventChargingState
|
||||
import info.nightscout.androidaps.events.EventNetworkChange
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.interfaces.PluginBase
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientResend
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.HtmlHelper.fromHtml
|
||||
import info.nightscout.androidaps.utils.ToastUtils
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class NSClientPlugin @Inject constructor(
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
private val aapsSchedulers: AapsSchedulers,
|
||||
private val rxBus: RxBusWrapper,
|
||||
resourceHelper: ResourceHelper,
|
||||
private val context: Context,
|
||||
private val fabricPrivacy: FabricPrivacy,
|
||||
private val sp: SP,
|
||||
private val nsClientReceiverDelegate: NsClientReceiverDelegate,
|
||||
private val config: Config,
|
||||
private val buildHelper: BuildHelper
|
||||
) : PluginBase(PluginDescription()
|
||||
.mainType(PluginType.GENERAL)
|
||||
.fragmentClass(NSClientFragment::class.java.name)
|
||||
.pluginIcon(R.drawable.ic_nightscout_syncs)
|
||||
.pluginName(R.string.nsclientinternal)
|
||||
.shortName(R.string.nsclientinternal_shortname)
|
||||
.preferencesId(R.xml.pref_nsclientinternal)
|
||||
.description(R.string.description_ns_client),
|
||||
aapsLogger, resourceHelper, injector
|
||||
) {
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
var handler: Handler? = null
|
||||
private val listLog: MutableList<EventNSClientNewLog> = ArrayList()
|
||||
var textLog = fromHtml("")
|
||||
var paused = false
|
||||
var autoscroll = false
|
||||
var status = ""
|
||||
var nsClientService: NSClientService? = null
|
||||
val isAllowed: Boolean
|
||||
get() = nsClientReceiverDelegate.allowed
|
||||
|
||||
init {
|
||||
if (config.NSCLIENT) {
|
||||
pluginDescription.alwaysEnabled(true).visibleByDefault(true)
|
||||
}
|
||||
if (handler == null) {
|
||||
val handlerThread = HandlerThread(NSClientPlugin::class.java.simpleName + "Handler")
|
||||
handlerThread.start()
|
||||
handler = Handler(handlerThread.looper)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
paused = sp.getBoolean(R.string.key_nsclientinternal_paused, false)
|
||||
autoscroll = sp.getBoolean(R.string.key_nsclientinternal_autoscroll, true)
|
||||
val intent = Intent(context, NSClientService::class.java)
|
||||
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
|
||||
super.onStart()
|
||||
nsClientReceiverDelegate.grabReceiversState()
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventNSClientStatus::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ event: EventNSClientStatus ->
|
||||
status = event.getStatus(resourceHelper)
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventNetworkChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventAppExit::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ if (nsClientService != null) context.unbindService(mConnection) }, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventNSClientNewLog::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ event: EventNSClientNewLog ->
|
||||
addToLog(event)
|
||||
aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText)
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventChargingState::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventNSClientResend::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ event -> resend(event.reason) }, fabricPrivacy::logException)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
context.applicationContext.unbindService(mConnection)
|
||||
disposable.clear()
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
|
||||
super.preprocessPreferences(preferenceFragment)
|
||||
if (config.NSCLIENT) {
|
||||
preferenceFragment.findPreference<PreferenceScreen>(resourceHelper.gs(R.string.ns_sync_options))?.isVisible = false
|
||||
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_create_announcements_from_errors))?.isVisible = false
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_create_announcements_from_carbs_req))?.isVisible = false
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_sync_use_absolute))?.isVisible = false
|
||||
} else {
|
||||
// APS or pumpControl mode
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_receive_profile_switch))?.isVisible = buildHelper.isEngineeringMode()
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_receive_insulin))?.isVisible = buildHelper.isEngineeringMode()
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_receive_carbs))?.isVisible = buildHelper.isEngineeringMode()
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_receive_temp_target))?.isVisible = buildHelper.isEngineeringMode()
|
||||
}
|
||||
}
|
||||
|
||||
private val mConnection: ServiceConnection = object : ServiceConnection {
|
||||
override fun onServiceDisconnected(name: ComponentName) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Service is disconnected")
|
||||
nsClientService = null
|
||||
}
|
||||
|
||||
override fun onServiceConnected(name: ComponentName, service: IBinder) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Service is connected")
|
||||
val mLocalBinder = service as NSClientService.LocalBinder
|
||||
@Suppress("UNNECESSARY_SAFE_CALL")
|
||||
nsClientService = mLocalBinder?.serviceInstance // is null when running in roboelectric
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized fun clearLog() {
|
||||
handler?.post {
|
||||
synchronized(listLog) { listLog.clear() }
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized private fun addToLog(ev: EventNSClientNewLog) {
|
||||
handler?.post {
|
||||
synchronized(listLog) {
|
||||
listLog.add(ev)
|
||||
// remove the first line if log is too large
|
||||
if (listLog.size >= Constants.MAX_LOG_LINES) {
|
||||
listLog.removeAt(0)
|
||||
}
|
||||
}
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized fun updateLog() {
|
||||
try {
|
||||
val newTextLog = StringBuilder()
|
||||
synchronized(listLog) {
|
||||
for (log in listLog) {
|
||||
newTextLog.append(log.toPreparedHtml())
|
||||
}
|
||||
}
|
||||
textLog = fromHtml(newTextLog.toString())
|
||||
} catch (e: OutOfMemoryError) {
|
||||
ToastUtils.showToastInUiThread(context, rxBus, "Out of memory!\nStop using this phone !!!", R.raw.error)
|
||||
}
|
||||
}
|
||||
|
||||
fun resend(reason: String) {
|
||||
nsClientService?.resend(reason)
|
||||
}
|
||||
|
||||
fun pause(newState: Boolean) {
|
||||
sp.putBoolean(R.string.key_nsclientinternal_paused, newState)
|
||||
paused = newState
|
||||
rxBus.send(EventPreferenceChange(resourceHelper, R.string.key_nsclientinternal_paused))
|
||||
}
|
||||
|
||||
fun url(): String = nsClientService?.nsURL ?: ""
|
||||
fun hasWritePermission(): Boolean = nsClientService?.hasWriteAuth ?: false
|
||||
|
||||
fun handleClearAlarm(originalAlarm: NSAlarm, silenceTimeInMilliseconds: Long) {
|
||||
if (!isEnabled(PluginType.GENERAL)) return
|
||||
if (!sp.getBoolean(R.string.key_ns_upload, false)) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Upload disabled. Message dropped")
|
||||
return
|
||||
}
|
||||
nsClientService?.sendAlarmAck(
|
||||
AlarmAck().also { ack ->
|
||||
ack.level = originalAlarm.level()
|
||||
ack.group = originalAlarm.group()
|
||||
ack.silenceTime = silenceTimeInMilliseconds
|
||||
})
|
||||
}
|
||||
|
||||
fun updateLatestDateReceivedIfNewer(latestReceived: Long) {
|
||||
nsClientService?.let { if (latestReceived > it.latestDateInReceivedData) it.latestDateInReceivedData = latestReceived }
|
||||
}
|
||||
}
|
|
@ -42,8 +42,9 @@ class NSClientRemoveWorker(
|
|||
@Inject lateinit var uel: UserEntryLogger
|
||||
|
||||
override fun doWork(): Result {
|
||||
val acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, true) && buildHelper.isEngineeringMode() || config.NSCLIENT
|
||||
if (!acceptNSData) return Result.success()
|
||||
// Do not accept removed data over WS. Only invalidated trough NSClient
|
||||
@Suppress("ConstantConditionIf")
|
||||
if (true) return Result.success()
|
||||
|
||||
var ret = Result.success()
|
||||
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.nsclient;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.events.EventChargingState;
|
||||
import info.nightscout.androidaps.events.EventNetworkChange;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.receivers.ReceiverStatusStore;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||
|
||||
@Singleton
|
||||
class NsClientReceiverDelegate {
|
||||
|
||||
private boolean allowedChargingState = true;
|
||||
private boolean allowedNetworkState = true;
|
||||
boolean allowed = true;
|
||||
|
||||
private RxBusWrapper rxBus;
|
||||
private ResourceHelper resourceHelper;
|
||||
private SP sp;
|
||||
private ReceiverStatusStore receiverStatusStore;
|
||||
|
||||
@Inject
|
||||
public NsClientReceiverDelegate(
|
||||
RxBusWrapper rxBus,
|
||||
ResourceHelper resourceHelper,
|
||||
SP sp,
|
||||
ReceiverStatusStore receiverStatusStore
|
||||
) {
|
||||
this.rxBus = rxBus;
|
||||
this.resourceHelper = resourceHelper;
|
||||
this.sp = sp;
|
||||
this.receiverStatusStore = receiverStatusStore;
|
||||
}
|
||||
|
||||
void grabReceiversState() {
|
||||
|
||||
receiverStatusStore.updateNetworkStatus();
|
||||
}
|
||||
|
||||
void onStatusEvent(EventPreferenceChange ev) {
|
||||
if (ev.isChanged(resourceHelper, R.string.key_ns_wifionly) ||
|
||||
ev.isChanged(resourceHelper, R.string.key_ns_wifi_ssids) ||
|
||||
ev.isChanged(resourceHelper, R.string.key_ns_allowroaming)
|
||||
) {
|
||||
receiverStatusStore.updateNetworkStatus();
|
||||
onStatusEvent(receiverStatusStore.getLastNetworkEvent());
|
||||
} else if (ev.isChanged(resourceHelper, R.string.key_ns_chargingonly)) {
|
||||
receiverStatusStore.broadcastChargingState();
|
||||
}
|
||||
}
|
||||
|
||||
void onStatusEvent(final EventChargingState ev) {
|
||||
boolean newChargingState = calculateStatus(ev);
|
||||
|
||||
if (newChargingState != allowedChargingState) {
|
||||
allowedChargingState = newChargingState;
|
||||
processStateChange();
|
||||
}
|
||||
}
|
||||
|
||||
void onStatusEvent(final EventNetworkChange ev) {
|
||||
boolean newNetworkState = calculateStatus(ev);
|
||||
|
||||
if (newNetworkState != allowedNetworkState) {
|
||||
allowedNetworkState = newNetworkState;
|
||||
processStateChange();
|
||||
}
|
||||
}
|
||||
|
||||
private void processStateChange() {
|
||||
boolean newAllowedState = allowedChargingState && allowedNetworkState;
|
||||
if (newAllowedState != allowed) {
|
||||
allowed = newAllowedState;
|
||||
rxBus.send(new EventPreferenceChange(resourceHelper.gs(R.string.key_nsclientinternal_paused)));
|
||||
}
|
||||
}
|
||||
|
||||
boolean calculateStatus(final EventChargingState ev) {
|
||||
boolean chargingOnly = sp.getBoolean(R.string.key_ns_chargingonly, false);
|
||||
boolean newAllowedState = true;
|
||||
|
||||
if (!ev.isCharging() && chargingOnly) {
|
||||
newAllowedState = false;
|
||||
}
|
||||
|
||||
return newAllowedState;
|
||||
}
|
||||
|
||||
boolean calculateStatus(final EventNetworkChange ev) {
|
||||
boolean wifiOnly = sp.getBoolean(R.string.key_ns_wifionly, false);
|
||||
String allowedSSIDstring = sp.getString(R.string.key_ns_wifi_ssids, "");
|
||||
String[] allowedSSIDs = allowedSSIDstring.split(";");
|
||||
if (allowedSSIDstring.isEmpty()) allowedSSIDs = new String[0];
|
||||
boolean allowRoaming = sp.getBoolean(R.string.key_ns_allowroaming, true);
|
||||
|
||||
boolean newAllowedState = true;
|
||||
|
||||
if (ev.getWifiConnected()) {
|
||||
if (allowedSSIDs.length != 0 && !Arrays.asList(allowedSSIDs).contains(ev.getSsid())) {
|
||||
newAllowedState = false;
|
||||
}
|
||||
} else {
|
||||
if ((!allowRoaming && ev.getRoaming()) || wifiOnly) {
|
||||
newAllowedState = false;
|
||||
}
|
||||
}
|
||||
|
||||
return newAllowedState;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package info.nightscout.androidaps.plugins.general.nsclient
|
||||
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.events.EventChargingState
|
||||
import info.nightscout.androidaps.events.EventNetworkChange
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.receivers.ReceiverStatusStore
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class NsClientReceiverDelegate @Inject constructor(
|
||||
private val rxBus: RxBusWrapper,
|
||||
private val resourceHelper: ResourceHelper,
|
||||
private val sp: SP,
|
||||
private val receiverStatusStore: ReceiverStatusStore
|
||||
) {
|
||||
|
||||
private var allowedChargingState = true
|
||||
private var allowedNetworkState = true
|
||||
var allowed = true
|
||||
|
||||
fun grabReceiversState() {
|
||||
receiverStatusStore.updateNetworkStatus()
|
||||
}
|
||||
|
||||
fun onStatusEvent(ev: EventPreferenceChange) {
|
||||
if (ev.isChanged(resourceHelper, R.string.key_ns_wifionly) ||
|
||||
ev.isChanged(resourceHelper, R.string.key_ns_wifi_ssids) ||
|
||||
ev.isChanged(resourceHelper, R.string.key_ns_allowroaming)) {
|
||||
receiverStatusStore.updateNetworkStatus()
|
||||
onStatusEvent(receiverStatusStore.lastNetworkEvent)
|
||||
} else if (ev.isChanged(resourceHelper, R.string.key_ns_chargingonly)) {
|
||||
receiverStatusStore.broadcastChargingState()
|
||||
}
|
||||
}
|
||||
|
||||
fun onStatusEvent(ev: EventChargingState) {
|
||||
val newChargingState = calculateStatus(ev)
|
||||
if (newChargingState != allowedChargingState) {
|
||||
allowedChargingState = newChargingState
|
||||
processStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
fun onStatusEvent(ev: EventNetworkChange?) {
|
||||
val newNetworkState = calculateStatus(ev)
|
||||
if (newNetworkState != allowedNetworkState) {
|
||||
allowedNetworkState = newNetworkState
|
||||
processStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
private fun processStateChange() {
|
||||
val newAllowedState = allowedChargingState && allowedNetworkState
|
||||
if (newAllowedState != allowed) {
|
||||
allowed = newAllowedState
|
||||
rxBus.send(EventPreferenceChange(resourceHelper.gs(R.string.key_nsclientinternal_paused)))
|
||||
}
|
||||
}
|
||||
|
||||
fun calculateStatus(ev: EventChargingState): Boolean {
|
||||
val chargingOnly = sp.getBoolean(R.string.key_ns_chargingonly, false)
|
||||
var newAllowedState = true
|
||||
if (!ev.isCharging && chargingOnly) {
|
||||
newAllowedState = false
|
||||
}
|
||||
return newAllowedState
|
||||
}
|
||||
|
||||
fun calculateStatus(ev: EventNetworkChange?): Boolean {
|
||||
val wifiOnly = sp.getBoolean(R.string.key_ns_wifionly, false)
|
||||
val allowedSsidString = sp.getString(R.string.key_ns_wifi_ssids, "")
|
||||
val allowedSSIDs: List<String> = if (allowedSsidString.isEmpty()) List(0) { "" } else allowedSsidString.split(";")
|
||||
val allowRoaming = sp.getBoolean(R.string.key_ns_allowroaming, true)
|
||||
var newAllowedState = true
|
||||
if (ev?.wifiConnected == true) {
|
||||
if (allowedSSIDs.isNotEmpty() && !allowedSSIDs.contains(ev.ssid)) {
|
||||
newAllowedState = false
|
||||
}
|
||||
} else {
|
||||
if (!allowRoaming && ev?.roaming == true || wifiOnly) {
|
||||
newAllowedState = false
|
||||
}
|
||||
}
|
||||
return newAllowedState
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.nsclient;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.j256.ormlite.dao.CloseableIterator;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
import info.nightscout.androidaps.db.DbRequest;
|
||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
|
||||
import info.nightscout.androidaps.interfaces.UploadQueueAdminInterface;
|
||||
import info.nightscout.androidaps.interfaces.UploadQueueInterface;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientResend;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService;
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 21.02.2016.
|
||||
*/
|
||||
public class UploadQueue implements UploadQueueAdminInterface {
|
||||
private final AAPSLogger aapsLogger;
|
||||
private final DatabaseHelperInterface databaseHelper;
|
||||
private final Context context;
|
||||
private final SP sp;
|
||||
private final RxBusWrapper rxBus;
|
||||
|
||||
public UploadQueue(
|
||||
AAPSLogger aapsLogger,
|
||||
DatabaseHelperInterface databaseHelper,
|
||||
Context context,
|
||||
SP sp,
|
||||
RxBusWrapper rxBus
|
||||
) {
|
||||
this.aapsLogger = aapsLogger;
|
||||
this.databaseHelper = databaseHelper;
|
||||
this.context = context;
|
||||
this.sp = sp;
|
||||
this.rxBus = rxBus;
|
||||
}
|
||||
|
||||
public String status() {
|
||||
return "QUEUE: " + databaseHelper.size(DatabaseHelper.DATABASE_DBREQUESTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long size() {
|
||||
return databaseHelper.size(DatabaseHelper.DATABASE_DBREQUESTS);
|
||||
}
|
||||
|
||||
private void startService() {
|
||||
if (NSClientService.handler == null) {
|
||||
context.startService(new Intent(context, NSClientService.class));
|
||||
SystemClock.sleep(2000);
|
||||
}
|
||||
}
|
||||
|
||||
public void add(final DbRequest dbr) {
|
||||
if (sp.getBoolean(R.string.key_ns_noupload, false)) return;
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Adding to queue: " + dbr.log());
|
||||
try {
|
||||
databaseHelper.create(dbr);
|
||||
} catch (Exception e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
rxBus.send(new EventNSClientResend("newdata"));
|
||||
}
|
||||
|
||||
@Override public void clearQueue() {
|
||||
startService();
|
||||
if (NSClientService.handler != null) {
|
||||
NSClientService.handler.post(() -> {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "ClearQueue");
|
||||
databaseHelper.deleteAllDbRequests();
|
||||
aapsLogger.debug(LTag.NSCLIENT, status());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeByMongoId(final String action, final String _id) {
|
||||
if (_id == null || _id.equals(""))
|
||||
return;
|
||||
startService();
|
||||
if (NSClientService.handler != null) {
|
||||
NSClientService.handler.post(() -> {
|
||||
databaseHelper.deleteDbRequestbyMongoId(action, _id);
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Removing " + _id + " from UploadQueue. " + status());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String textList() {
|
||||
String result = "";
|
||||
CloseableIterator<DbRequest> iterator;
|
||||
try {
|
||||
iterator = databaseHelper.getDbRequestIterator();
|
||||
try {
|
||||
while (iterator.hasNext()) {
|
||||
DbRequest dbr = iterator.next();
|
||||
result += "<br>";
|
||||
result += dbr.action.toUpperCase() + " ";
|
||||
result += dbr.collection + ": ";
|
||||
result += dbr.data;
|
||||
}
|
||||
} finally {
|
||||
iterator.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,913 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.nsclient.services;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import androidx.work.OneTimeWorkRequest;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.j256.ormlite.dao.CloseableIterator;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.DaggerService;
|
||||
import dagger.android.HasAndroidInjector;
|
||||
import info.nightscout.androidaps.interfaces.Config;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.database.AppRepository;
|
||||
import info.nightscout.androidaps.db.DbRequest;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventConfigBuilderChange;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.interfaces.DataSyncSelector;
|
||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.interfaces.UploadQueueInterface;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.general.food.FoodPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddAckWorker;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddUpdateWorker;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientMbgWorker;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientRemoveWorker;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientUpdateRemoveAckWorker;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.acks.NSAddAck;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.acks.NSAuthAck;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.acks.NSUpdateAck;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI;
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction;
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.source.NSClientSourcePlugin;
|
||||
import info.nightscout.androidaps.receivers.DataWorker;
|
||||
import info.nightscout.androidaps.services.Intents;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers;
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.socket.client.IO;
|
||||
import io.socket.client.Socket;
|
||||
import io.socket.emitter.Emitter;
|
||||
|
||||
public class NSClientService extends DaggerService {
|
||||
@Inject HasAndroidInjector injector;
|
||||
@Inject AAPSLogger aapsLogger;
|
||||
@Inject AapsSchedulers aapsSchedulers;
|
||||
@Inject NSSettingsStatus nsSettingsStatus;
|
||||
@Inject NSDeviceStatus nsDeviceStatus;
|
||||
@Inject DatabaseHelperInterface databaseHelper;
|
||||
@Inject RxBusWrapper rxBus;
|
||||
@Inject ResourceHelper resourceHelper;
|
||||
@Inject SP sp;
|
||||
@Inject FabricPrivacy fabricPrivacy;
|
||||
@Inject NSClientPlugin nsClientPlugin;
|
||||
@Inject BuildHelper buildHelper;
|
||||
@Inject Config config;
|
||||
@Inject DateUtil dateUtil;
|
||||
@Inject UploadQueueInterface uploadQueue;
|
||||
@Inject DataWorker dataWorker;
|
||||
@Inject DataSyncSelector dataSyncSelector;
|
||||
@Inject AppRepository repository;
|
||||
|
||||
private final CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
static public PowerManager.WakeLock mWakeLock;
|
||||
private final IBinder mBinder = new NSClientService.LocalBinder();
|
||||
|
||||
static public Handler handler;
|
||||
|
||||
public static Socket mSocket;
|
||||
public static boolean isConnected = false;
|
||||
public static boolean hasWriteAuth = false;
|
||||
private static Integer dataCounter = 0;
|
||||
private static Integer connectCounter = 0;
|
||||
|
||||
|
||||
private boolean nsEnabled = false;
|
||||
static public String nsURL = "";
|
||||
private String nsAPISecret = "";
|
||||
private String nsDevice = "";
|
||||
private final Integer nsHours = 48;
|
||||
|
||||
public long lastResendTime = 0;
|
||||
public long lastAckTime = 0;
|
||||
|
||||
public long latestDateInReceivedData = 0;
|
||||
|
||||
private String nsAPIhashCode = "";
|
||||
|
||||
private final ArrayList<Long> reconnections = new ArrayList<>();
|
||||
private final int WATCHDOG_INTERVAL_MINUTES = 2;
|
||||
private final int WATCHDOG_RECONNECT_IN = 15;
|
||||
private final int WATCHDOG_MAX_CONNECTIONS = 5;
|
||||
|
||||
public NSClientService() {
|
||||
super();
|
||||
if (handler == null) {
|
||||
HandlerThread handlerThread = new HandlerThread(NSClientService.class.getSimpleName() + "Handler");
|
||||
handlerThread.start();
|
||||
handler = new Handler(handlerThread.getLooper());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:NSClientService");
|
||||
mWakeLock.acquire();
|
||||
|
||||
initialize();
|
||||
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventConfigBuilderChange.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(event -> {
|
||||
if (nsEnabled != nsClientPlugin.isEnabled(PluginType.GENERAL)) {
|
||||
latestDateInReceivedData = 0;
|
||||
destroy();
|
||||
initialize();
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventPreferenceChange.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(event -> {
|
||||
if (event.isChanged(resourceHelper, R.string.key_nsclientinternal_url) ||
|
||||
event.isChanged(resourceHelper, R.string.key_nsclientinternal_api_secret) ||
|
||||
event.isChanged(resourceHelper, R.string.key_nsclientinternal_paused)
|
||||
) {
|
||||
latestDateInReceivedData = 0;
|
||||
destroy();
|
||||
initialize();
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventAppExit.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(event -> {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "EventAppExit received");
|
||||
destroy();
|
||||
stopSelf();
|
||||
}, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventNSClientRestart.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(event -> {
|
||||
latestDateInReceivedData = 0;
|
||||
restart();
|
||||
}, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(NSAuthAck.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(this::processAuthAck, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(NSUpdateAck.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(this::processUpdateAck, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(NSAddAck.class)
|
||||
.observeOn(aapsSchedulers.getIo())
|
||||
.subscribe(this::processAddAck, fabricPrivacy::logException)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
disposable.clear();
|
||||
if (mWakeLock.isHeld()) mWakeLock.release();
|
||||
}
|
||||
|
||||
public void processAddAck(NSAddAck ack) {
|
||||
lastAckTime = dateUtil.now();
|
||||
dataWorker.enqueue(
|
||||
new OneTimeWorkRequest.Builder(NSClientAddAckWorker.class)
|
||||
.setInputData(dataWorker.storeInputData(ack, null))
|
||||
.build());
|
||||
}
|
||||
|
||||
public void processUpdateAck(NSUpdateAck ack) {
|
||||
lastAckTime = dateUtil.now();
|
||||
dataWorker.enqueue(
|
||||
new OneTimeWorkRequest.Builder(NSClientUpdateRemoveAckWorker.class)
|
||||
.setInputData(dataWorker.storeInputData(ack, null))
|
||||
.build());
|
||||
}
|
||||
|
||||
public void processAuthAck(NSAuthAck ack) {
|
||||
String connectionStatus = "Authenticated (";
|
||||
if (ack.read) connectionStatus += "R";
|
||||
if (ack.write) connectionStatus += "W";
|
||||
if (ack.write_treatment) connectionStatus += "T";
|
||||
connectionStatus += ')';
|
||||
isConnected = true;
|
||||
hasWriteAuth = ack.write && ack.write_treatment;
|
||||
rxBus.send(new EventNSClientStatus(connectionStatus));
|
||||
rxBus.send(new EventNSClientNewLog("AUTH", connectionStatus));
|
||||
if (!ack.write) {
|
||||
rxBus.send(new EventNSClientNewLog("ERROR", "Write permission not granted !!!!"));
|
||||
}
|
||||
if (!ack.write_treatment) {
|
||||
rxBus.send(new EventNSClientNewLog("ERROR", "Write treatment permission not granted !!!!"));
|
||||
}
|
||||
if (!hasWriteAuth) {
|
||||
Notification noperm = new Notification(Notification.NSCLIENT_NO_WRITE_PERMISSION, resourceHelper.gs(R.string.nowritepermission), Notification.URGENT);
|
||||
rxBus.send(new EventNewNotification(noperm));
|
||||
} else {
|
||||
rxBus.send(new EventDismissNotification(Notification.NSCLIENT_NO_WRITE_PERMISSION));
|
||||
}
|
||||
}
|
||||
|
||||
public class LocalBinder extends Binder {
|
||||
public NSClientService getServiceInstance() {
|
||||
return NSClientService.this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void initialize() {
|
||||
dataCounter = 0;
|
||||
|
||||
readPreferences();
|
||||
|
||||
if (!nsAPISecret.equals(""))
|
||||
nsAPIhashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString();
|
||||
|
||||
rxBus.send(new EventNSClientStatus("Initializing"));
|
||||
if (!nsClientPlugin.isAllowed()) {
|
||||
rxBus.send(new EventNSClientNewLog("NSCLIENT", "not allowed"));
|
||||
rxBus.send(new EventNSClientStatus("Not allowed"));
|
||||
} else if (nsClientPlugin.paused) {
|
||||
rxBus.send(new EventNSClientNewLog("NSCLIENT", "paused"));
|
||||
rxBus.send(new EventNSClientStatus("Paused"));
|
||||
} else if (!nsEnabled) {
|
||||
rxBus.send(new EventNSClientNewLog("NSCLIENT", "disabled"));
|
||||
rxBus.send(new EventNSClientStatus("Disabled"));
|
||||
} else if (!nsURL.equals("") && (buildHelper.isEngineeringMode() || nsURL.toLowerCase().startsWith("https://"))) {
|
||||
try {
|
||||
rxBus.send(new EventNSClientStatus("Connecting ..."));
|
||||
IO.Options opt = new IO.Options();
|
||||
opt.forceNew = true;
|
||||
opt.reconnection = true;
|
||||
mSocket = IO.socket(nsURL, opt);
|
||||
mSocket.on(Socket.EVENT_CONNECT, onConnect);
|
||||
mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
|
||||
mSocket.on(Socket.EVENT_ERROR, onError);
|
||||
mSocket.on(Socket.EVENT_CONNECT_ERROR, onError);
|
||||
mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onError);
|
||||
mSocket.on(Socket.EVENT_PING, onPing);
|
||||
rxBus.send(new EventNSClientNewLog("NSCLIENT", "do connect"));
|
||||
mSocket.connect();
|
||||
mSocket.on("dataUpdate", onDataUpdate);
|
||||
mSocket.on("announcement", onAnnouncement);
|
||||
mSocket.on("alarm", onAlarm);
|
||||
mSocket.on("urgent_alarm", onUrgentAlarm);
|
||||
mSocket.on("clear_alarm", onClearAlarm);
|
||||
} catch (URISyntaxException | RuntimeException e) {
|
||||
rxBus.send(new EventNSClientNewLog("NSCLIENT", "Wrong URL syntax"));
|
||||
rxBus.send(new EventNSClientStatus("Wrong URL syntax"));
|
||||
}
|
||||
} else if (nsURL.toLowerCase().startsWith("http://")) {
|
||||
rxBus.send(new EventNSClientNewLog("NSCLIENT", "NS URL not encrypted"));
|
||||
rxBus.send(new EventNSClientStatus("Not encrypted"));
|
||||
} else {
|
||||
rxBus.send(new EventNSClientNewLog("NSCLIENT", "No NS URL specified"));
|
||||
rxBus.send(new EventNSClientStatus("Not configured"));
|
||||
}
|
||||
}
|
||||
|
||||
private final Emitter.Listener onConnect = new Emitter.Listener() {
|
||||
@Override
|
||||
public void call(Object... args) {
|
||||
connectCounter++;
|
||||
String socketId = mSocket != null ? mSocket.id() : "NULL";
|
||||
rxBus.send(new EventNSClientNewLog("NSCLIENT", "connect #" + connectCounter + " event. ID: " + socketId));
|
||||
if (mSocket != null)
|
||||
sendAuthMessage(new NSAuthAck(rxBus));
|
||||
watchdog();
|
||||
}
|
||||
};
|
||||
|
||||
void watchdog() {
|
||||
synchronized (reconnections) {
|
||||
long now = dateUtil.now();
|
||||
reconnections.add(now);
|
||||
for (int i = 0; i < reconnections.size(); i++) {
|
||||
Long r = reconnections.get(i);
|
||||
if (r < now - T.mins(WATCHDOG_INTERVAL_MINUTES).msecs()) {
|
||||
reconnections.remove(r);
|
||||
}
|
||||
}
|
||||
rxBus.send(new EventNSClientNewLog("WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " mins: " + reconnections.size() + "/" + WATCHDOG_MAX_CONNECTIONS));
|
||||
if (reconnections.size() >= WATCHDOG_MAX_CONNECTIONS) {
|
||||
Notification n = new Notification(Notification.NS_MALFUNCTION, resourceHelper.gs(R.string.nsmalfunction), Notification.URGENT);
|
||||
rxBus.send(new EventNewNotification(n));
|
||||
rxBus.send(new EventNSClientNewLog("WATCHDOG", "pausing for " + WATCHDOG_RECONNECT_IN + " mins"));
|
||||
nsClientPlugin.pause(true);
|
||||
rxBus.send(new EventNSClientUpdateGUI());
|
||||
new Thread(() -> {
|
||||
SystemClock.sleep(T.mins(WATCHDOG_RECONNECT_IN).msecs());
|
||||
rxBus.send(new EventNSClientNewLog("WATCHDOG", "reenabling NSClient"));
|
||||
nsClientPlugin.pause(false);
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Emitter.Listener onDisconnect = new Emitter.Listener() {
|
||||
@Override
|
||||
public void call(Object... args) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "disconnect reason: {}", args);
|
||||
rxBus.send(new EventNSClientNewLog("NSCLIENT", "disconnect event"));
|
||||
}
|
||||
};
|
||||
|
||||
public synchronized void destroy() {
|
||||
if (mSocket != null) {
|
||||
mSocket.off(Socket.EVENT_CONNECT);
|
||||
mSocket.off(Socket.EVENT_DISCONNECT);
|
||||
mSocket.off(Socket.EVENT_PING);
|
||||
mSocket.off("dataUpdate");
|
||||
mSocket.off("announcement");
|
||||
mSocket.off("alarm");
|
||||
mSocket.off("urgent_alarm");
|
||||
mSocket.off("clear_alarm");
|
||||
|
||||
rxBus.send(new EventNSClientNewLog("NSCLIENT", "destroy"));
|
||||
isConnected = false;
|
||||
hasWriteAuth = false;
|
||||
mSocket.disconnect();
|
||||
mSocket = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendAuthMessage(NSAuthAck ack) {
|
||||
JSONObject authMessage = new JSONObject();
|
||||
try {
|
||||
authMessage.put("client", "Android_" + nsDevice);
|
||||
authMessage.put("history", nsHours);
|
||||
authMessage.put("status", true); // receive status
|
||||
authMessage.put("from", latestDateInReceivedData); // send data newer than
|
||||
authMessage.put("secret", nsAPIhashCode);
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
return;
|
||||
}
|
||||
rxBus.send(new EventNSClientNewLog("AUTH", "requesting auth"));
|
||||
if (mSocket != null)
|
||||
mSocket.emit("authorize", authMessage, ack);
|
||||
}
|
||||
|
||||
public void readPreferences() {
|
||||
nsEnabled = nsClientPlugin.isEnabled(PluginType.GENERAL);
|
||||
nsURL = sp.getString(R.string.key_nsclientinternal_url, "");
|
||||
nsAPISecret = sp.getString(R.string.key_nsclientinternal_api_secret, "");
|
||||
nsDevice = sp.getString("careportal_enteredby", "");
|
||||
}
|
||||
|
||||
private final Emitter.Listener onError = new Emitter.Listener() {
|
||||
@Override
|
||||
public void call(final Object... args) {
|
||||
String msg = "Unknown Error";
|
||||
if (args.length > 0 && args[0] != null) {
|
||||
msg = args[0].toString();
|
||||
}
|
||||
rxBus.send(new EventNSClientNewLog("ERROR", msg));
|
||||
}
|
||||
};
|
||||
|
||||
private final Emitter.Listener onPing = new Emitter.Listener() {
|
||||
@Override
|
||||
public void call(final Object... args) {
|
||||
rxBus.send(new EventNSClientNewLog("PING", "received"));
|
||||
// send data if there is something waiting
|
||||
resend("Ping received");
|
||||
}
|
||||
};
|
||||
|
||||
private final Emitter.Listener onAnnouncement = new Emitter.Listener() {
|
||||
/*
|
||||
{
|
||||
"level":0,
|
||||
"title":"Announcement",
|
||||
"message":"test",
|
||||
"plugin":{"name":"treatmentnotify","label":"Treatment Notifications","pluginType":"notification","enabled":true},
|
||||
"group":"Announcement",
|
||||
"isAnnouncement":true,
|
||||
"key":"9ac46ad9a1dcda79dd87dae418fce0e7955c68da"
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
public void call(final Object... args) {
|
||||
JSONObject data;
|
||||
try {
|
||||
data = (JSONObject) args[0];
|
||||
handleAnnouncement(data);
|
||||
} catch (Exception e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final Emitter.Listener onAlarm = new Emitter.Listener() {
|
||||
/*
|
||||
{
|
||||
"level":1,
|
||||
"title":"Warning HIGH",
|
||||
"message":"BG Now: 5 -0.2 → mmol\/L\nRaw BG: 4.8 mmol\/L Čistý\nBG 15m: 4.8 mmol\/L\nIOB: -0.02U\nCOB: 0g",
|
||||
"eventName":"high",
|
||||
"plugin":{"name":"simplealarms","label":"Simple Alarms","pluginType":"notification","enabled":true},
|
||||
"pushoverSound":"climb",
|
||||
"debug":{"lastSGV":5,"thresholds":{"bgHigh":180,"bgTargetTop":75,"bgTargetBottom":72,"bgLow":70}},
|
||||
"group":"default",
|
||||
"key":"simplealarms_1"
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
public void call(final Object... args) {
|
||||
JSONObject data;
|
||||
try {
|
||||
data = (JSONObject) args[0];
|
||||
handleAlarm(data);
|
||||
} catch (Exception e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final Emitter.Listener onUrgentAlarm = args -> {
|
||||
JSONObject data;
|
||||
try {
|
||||
data = (JSONObject) args[0];
|
||||
handleUrgentAlarm(data);
|
||||
} catch (Exception e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
};
|
||||
|
||||
private final Emitter.Listener onClearAlarm = new Emitter.Listener() {
|
||||
/*
|
||||
{
|
||||
"clear":true,
|
||||
"title":"All Clear",
|
||||
"message":"default - Urgent was ack'd",
|
||||
"group":"default"
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
public void call(final Object... args) {
|
||||
JSONObject data;
|
||||
try {
|
||||
data = (JSONObject) args[0];
|
||||
rxBus.send(new EventNSClientNewLog("CLEARALARM", "received"));
|
||||
rxBus.send(new EventDismissNotification(Notification.NS_ALARM));
|
||||
rxBus.send(new EventDismissNotification(Notification.NS_URGENT_ALARM));
|
||||
aapsLogger.debug(LTag.NSCLIENT, data.toString());
|
||||
} catch (Exception e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final Emitter.Listener onDataUpdate = new Emitter.Listener() {
|
||||
@Override
|
||||
public void call(final Object... args) {
|
||||
NSClientService.handler.post(() -> {
|
||||
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||
"AndroidAPS:NSClientService_onDataUpdate");
|
||||
wakeLock.acquire();
|
||||
try {
|
||||
|
||||
JSONObject data = (JSONObject) args[0];
|
||||
boolean broadcastProfile = false;
|
||||
try {
|
||||
// delta means only increment/changes are comming
|
||||
boolean isDelta = data.has("delta");
|
||||
boolean isFull = !isDelta;
|
||||
rxBus.send(new EventNSClientNewLog("DATA", "Data packet #" + dataCounter++ + (isDelta ? " delta" : " full")));
|
||||
|
||||
if (data.has("status")) {
|
||||
JSONObject status = data.getJSONObject("status");
|
||||
nsSettingsStatus.handleNewData(status);
|
||||
} else if (!isDelta) {
|
||||
rxBus.send(new EventNSClientNewLog("ERROR", "Unsupported Nightscout version !!!!"));
|
||||
}
|
||||
|
||||
if (data.has("profiles")) {
|
||||
JSONArray profiles = data.getJSONArray("profiles");
|
||||
if (profiles.length() > 0) {
|
||||
// take the newest
|
||||
JSONObject profileStoreJson = (JSONObject) profiles.get(profiles.length() - 1);
|
||||
rxBus.send(new EventNSClientNewLog("PROFILE", "profile received"));
|
||||
dataWorker.enqueue(
|
||||
new OneTimeWorkRequest.Builder(NSProfilePlugin.NSProfileWorker.class)
|
||||
.setInputData(dataWorker.storeInputData(profileStoreJson, null))
|
||||
.build());
|
||||
|
||||
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("profile", profileStoreJson.toString());
|
||||
bundle.putBoolean("delta", isDelta);
|
||||
Intent intent = new Intent(Intents.ACTION_NEW_PROFILE);
|
||||
intent.putExtras(bundle);
|
||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.has("treatments")) {
|
||||
JSONArray treatments = data.getJSONArray("treatments");
|
||||
JSONArray removedTreatments = new JSONArray();
|
||||
JSONArray addedOrUpdatedTreatments = new JSONArray();
|
||||
if (treatments.length() > 0)
|
||||
rxBus.send(new EventNSClientNewLog("DATA", "received " + treatments.length() + " treatments"));
|
||||
for (Integer index = 0; index < treatments.length(); index++) {
|
||||
JSONObject jsonTreatment = treatments.getJSONObject(index);
|
||||
String action = JsonHelper.safeGetStringAllowNull(jsonTreatment, "action", null);
|
||||
long mills = JsonHelper.safeGetLong(jsonTreatment, "mills");
|
||||
|
||||
if (action == null) addedOrUpdatedTreatments.put(jsonTreatment);
|
||||
else if (action.equals("update"))
|
||||
addedOrUpdatedTreatments.put(jsonTreatment);
|
||||
else if (action.equals("remove") && mills > dateUtil.now() - T.days(1).msecs()) // handle 1 day old deletions only
|
||||
removedTreatments.put(jsonTreatment);
|
||||
}
|
||||
if (removedTreatments.length() > 0) {
|
||||
dataWorker.enqueue(
|
||||
new OneTimeWorkRequest.Builder(NSClientRemoveWorker.class)
|
||||
.setInputData(dataWorker.storeInputData(removedTreatments, null))
|
||||
.build());
|
||||
|
||||
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("treatments", removedTreatments.toString());
|
||||
bundle.putBoolean("delta", isDelta);
|
||||
Intent intent = new Intent(Intents.ACTION_REMOVED_TREATMENT);
|
||||
intent.putExtras(bundle);
|
||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
if (addedOrUpdatedTreatments.length() > 0) {
|
||||
dataWorker.enqueue(
|
||||
new OneTimeWorkRequest.Builder(NSClientAddUpdateWorker.class)
|
||||
.setInputData(dataWorker.storeInputData(addedOrUpdatedTreatments, null))
|
||||
.build());
|
||||
|
||||
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
|
||||
List<JSONArray> splitted = splitArray(addedOrUpdatedTreatments);
|
||||
for (JSONArray part : splitted) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("treatments", part.toString());
|
||||
bundle.putBoolean("delta", isDelta);
|
||||
Intent intent = new Intent(Intents.ACTION_CHANGED_TREATMENT);
|
||||
intent.putExtras(bundle);
|
||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.has("devicestatus")) {
|
||||
JSONArray devicestatuses = data.getJSONArray("devicestatus");
|
||||
if (devicestatuses.length() > 0) {
|
||||
rxBus.send(new EventNSClientNewLog("DATA", "received " + devicestatuses.length() + " device statuses"));
|
||||
nsDeviceStatus.handleNewData(devicestatuses);
|
||||
}
|
||||
}
|
||||
if (data.has("food")) {
|
||||
JSONArray foods = data.getJSONArray("food");
|
||||
if (foods.length() > 0)
|
||||
rxBus.send(new EventNSClientNewLog("DATA", "received " + foods.length() + " foods"));
|
||||
dataWorker.enqueue(
|
||||
new OneTimeWorkRequest.Builder(FoodPlugin.FoodWorker.class)
|
||||
.setInputData(dataWorker.storeInputData(foods, null))
|
||||
.build());
|
||||
}
|
||||
//noinspection SpellCheckingInspection
|
||||
if (data.has("mbgs")) {
|
||||
JSONArray mbgArray = data.getJSONArray("mbgs");
|
||||
if (mbgArray.length() > 0)
|
||||
rxBus.send(new EventNSClientNewLog("DATA", "received " + mbgArray.length() + " mbgs"));
|
||||
dataWorker.enqueue(
|
||||
new OneTimeWorkRequest.Builder(NSClientMbgWorker.class)
|
||||
.setInputData(dataWorker.storeInputData(mbgArray, null))
|
||||
.build());
|
||||
}
|
||||
if (data.has("cals")) {
|
||||
JSONArray cals = data.getJSONArray("cals");
|
||||
if (cals.length() > 0)
|
||||
rxBus.send(new EventNSClientNewLog("DATA", "received " + cals.length() + " cals"));
|
||||
// Calibrations ignored
|
||||
}
|
||||
if (data.has("sgvs")) {
|
||||
JSONArray sgvs = data.getJSONArray("sgvs");
|
||||
if (sgvs.length() > 0)
|
||||
rxBus.send(new EventNSClientNewLog("DATA", "received " + sgvs.length() + " sgvs"));
|
||||
|
||||
dataWorker.enqueue(new OneTimeWorkRequest.Builder(NSClientSourcePlugin.NSClientSourceWorker.class)
|
||||
.setInputData(dataWorker.storeInputData(sgvs, null))
|
||||
.build());
|
||||
|
||||
List<JSONArray> splitted = splitArray(sgvs);
|
||||
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
|
||||
for (JSONArray part : splitted) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("sgvs", part.toString());
|
||||
bundle.putBoolean("delta", isDelta);
|
||||
Intent intent = new Intent(Intents.ACTION_NEW_SGV);
|
||||
intent.putExtras(bundle);
|
||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
rxBus.send(new EventNSClientNewLog("LAST", dateUtil.dateAndTimeString(latestDateInReceivedData)));
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
//rxBus.send(new EventNSClientNewLog("NSCLIENT", "onDataUpdate end");
|
||||
} finally {
|
||||
if (wakeLock.isHeld()) wakeLock.release();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
public void dbUpdate(DbRequest dbr, NSUpdateAck ack) {
|
||||
try {
|
||||
if (!isConnected || !hasWriteAuth) return;
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("collection", dbr.collection);
|
||||
message.put("_id", dbr._id);
|
||||
message.put("data", new JSONObject(dbr.data));
|
||||
mSocket.emit("dbUpdate", message, ack);
|
||||
rxBus.send(new EventNSClientNewLog("DBUPDATE " + dbr.collection, "Sent " + dbr._id));
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void dbUpdate(String collection, String _id, JSONObject data, Object originalObject) {
|
||||
try {
|
||||
if (!isConnected || !hasWriteAuth) return;
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("collection", collection);
|
||||
message.put("_id", _id);
|
||||
message.put("data", data);
|
||||
mSocket.emit("dbUpdate", message, new NSUpdateAck("dbUpdate", _id, aapsLogger, rxBus, originalObject));
|
||||
rxBus.send(new EventNSClientNewLog("DBUPDATE " + collection, "Sent " + originalObject.getClass().getSimpleName() + " " + _id));
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void dbRemove(DbRequest dbr, NSUpdateAck ack) {
|
||||
try {
|
||||
if (!isConnected || !hasWriteAuth) return;
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("collection", dbr.collection);
|
||||
message.put("_id", dbr._id);
|
||||
mSocket.emit("dbRemove", message, ack);
|
||||
rxBus.send(new EventNSClientNewLog("DBREMOVE " + dbr.collection, "Sent " + dbr._id));
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void dbRemove(String collection, String _id, Object originalObject) {
|
||||
try {
|
||||
if (!isConnected || !hasWriteAuth) return;
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("collection", collection);
|
||||
message.put("_id", _id);
|
||||
mSocket.emit("dbRemove", message, new NSUpdateAck("dbRemove", _id, aapsLogger, rxBus, originalObject));
|
||||
rxBus.send(new EventNSClientNewLog("DBREMOVE " + collection, "Sent " + originalObject.getClass().getSimpleName() + " " + _id));
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void dbAdd(DbRequest dbr, NSAddAck ack) {
|
||||
try {
|
||||
if (!isConnected || !hasWriteAuth) return;
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("collection", dbr.collection);
|
||||
message.put("data", new JSONObject(dbr.data));
|
||||
mSocket.emit("dbAdd", message, ack);
|
||||
rxBus.send(new EventNSClientNewLog("DBADD " + dbr.collection, "Sent " + dbr.nsClientID));
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void dbAdd(String collection, JSONObject data, Object originalObject) {
|
||||
try {
|
||||
if (!isConnected || !hasWriteAuth) return;
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("collection", collection);
|
||||
message.put("data", data);
|
||||
mSocket.emit("dbAdd", message, new NSAddAck(aapsLogger, rxBus, originalObject));
|
||||
rxBus.send(new EventNSClientNewLog("DBADD " + collection, "Sent " + originalObject.getClass().getSimpleName() + " " + data));
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendAlarmAck(AlarmAck alarmAck) {
|
||||
if (!isConnected || !hasWriteAuth) return;
|
||||
mSocket.emit("ack", alarmAck.level, alarmAck.group, alarmAck.silenceTime);
|
||||
rxBus.send(new EventNSClientNewLog("ALARMACK ", alarmAck.level + " " + alarmAck.group + " " + alarmAck.silenceTime));
|
||||
}
|
||||
|
||||
public void resend(final String reason) {
|
||||
if (!isConnected || !hasWriteAuth) return;
|
||||
|
||||
handler.post(() -> {
|
||||
if (mSocket == null || !mSocket.connected()) return;
|
||||
|
||||
rxBus.send(new EventNSClientNewLog("QUEUE", "Resend started: " + reason));
|
||||
|
||||
if (lastAckTime > System.currentTimeMillis() - 10 * 1000L) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Skipping resend by lastAckTime: " + ((System.currentTimeMillis() - lastAckTime) / 1000L) + " sec");
|
||||
return;
|
||||
}
|
||||
|
||||
dataSyncSelector.processChangedBolusesCompat();
|
||||
dataSyncSelector.processChangedCarbsCompat();
|
||||
dataSyncSelector.processChangedBolusCalculatorResultsCompat();
|
||||
dataSyncSelector.processChangedTemporaryBasalsCompat();
|
||||
dataSyncSelector.processChangedExtendedBolusesCompat();
|
||||
dataSyncSelector.processChangedProfileSwitchesCompat();
|
||||
dataSyncSelector.processChangedGlucoseValuesCompat();
|
||||
dataSyncSelector.processChangedTempTargetsCompat();
|
||||
dataSyncSelector.processChangedFoodsCompat();
|
||||
dataSyncSelector.processChangedTherapyEventsCompat();
|
||||
dataSyncSelector.processChangedDeviceStatusesCompat();
|
||||
|
||||
if (uploadQueue.size() == 0)
|
||||
return;
|
||||
|
||||
if (lastResendTime > System.currentTimeMillis() - 10 * 1000L) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Skipping resend by lastResendTime: " + ((System.currentTimeMillis() - lastResendTime) / 1000L) + " sec");
|
||||
return;
|
||||
}
|
||||
lastResendTime = System.currentTimeMillis();
|
||||
|
||||
CloseableIterator<DbRequest> iterator;
|
||||
int maxcount = 30;
|
||||
try {
|
||||
iterator = databaseHelper.getDbRequestIterator();
|
||||
try {
|
||||
while (iterator.hasNext() && maxcount > 0) {
|
||||
DbRequest dbr = iterator.next();
|
||||
if (dbr.action.equals("dbAdd")) {
|
||||
NSAddAck addAck = new NSAddAck(aapsLogger, rxBus, null);
|
||||
dbAdd(dbr, addAck);
|
||||
} else if (dbr.action.equals("dbRemove")) {
|
||||
NSUpdateAck removeAck = new NSUpdateAck("dbRemove", dbr._id, aapsLogger, rxBus, null);
|
||||
dbRemove(dbr, removeAck);
|
||||
} else if (dbr.action.equals("dbUpdate")) {
|
||||
NSUpdateAck updateAck = new NSUpdateAck("dbUpdate", dbr._id, aapsLogger, rxBus, null);
|
||||
dbUpdate(dbr, updateAck);
|
||||
}
|
||||
maxcount--;
|
||||
}
|
||||
} finally {
|
||||
iterator.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
|
||||
rxBus.send(new EventNSClientNewLog("QUEUE", "Resend ended: " + reason));
|
||||
});
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
destroy();
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void handleAnnouncement(JSONObject announcement) {
|
||||
boolean defaultVal = config.getNSCLIENT();
|
||||
if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) {
|
||||
NSAlarm nsAlarm = new NSAlarm(announcement);
|
||||
Notification notification = new NotificationWithAction(injector, nsAlarm);
|
||||
rxBus.send(new EventNewNotification(notification));
|
||||
rxBus.send(new EventNSClientNewLog("ANNOUNCEMENT", JsonHelper.safeGetString(announcement, "message", "received")));
|
||||
aapsLogger.debug(LTag.NSCLIENT, announcement.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleAlarm(JSONObject alarm) {
|
||||
boolean defaultVal = config.getNSCLIENT();
|
||||
if (sp.getBoolean(R.string.key_ns_alarms, defaultVal)) {
|
||||
long snoozedTo = sp.getLong(R.string.key_snoozedTo, 0L);
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
|
||||
NSAlarm nsAlarm = new NSAlarm(alarm);
|
||||
Notification notification = new NotificationWithAction(injector, nsAlarm);
|
||||
rxBus.send(new EventNewNotification(notification));
|
||||
}
|
||||
rxBus.send(new EventNSClientNewLog("ALARM", JsonHelper.safeGetString(alarm, "message", "received")));
|
||||
aapsLogger.debug(LTag.NSCLIENT, alarm.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleUrgentAlarm(JSONObject alarm) {
|
||||
boolean defaultVal = config.getNSCLIENT();
|
||||
if (sp.getBoolean(R.string.key_ns_alarms, defaultVal)) {
|
||||
long snoozedTo = sp.getLong(R.string.key_snoozedTo, 0L);
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
|
||||
NSAlarm nsAlarm = new NSAlarm(alarm);
|
||||
Notification notification = new NotificationWithAction(injector, nsAlarm);
|
||||
rxBus.send(new EventNewNotification(notification));
|
||||
}
|
||||
rxBus.send(new EventNSClientNewLog("URGENTALARM", JsonHelper.safeGetString(alarm, "message", "received")));
|
||||
aapsLogger.debug(LTag.NSCLIENT, alarm.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public List<JSONArray> splitArray(JSONArray array) {
|
||||
List<JSONArray> ret = new ArrayList<>();
|
||||
try {
|
||||
int size = array.length();
|
||||
int count = 0;
|
||||
JSONArray newarr = null;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (count == 0) {
|
||||
if (newarr != null) {
|
||||
ret.add(newarr);
|
||||
}
|
||||
newarr = new JSONArray();
|
||||
count = 20;
|
||||
}
|
||||
newarr.put(array.get(i));
|
||||
--count;
|
||||
}
|
||||
if (newarr != null && newarr.length() > 0) {
|
||||
ret.add(newarr);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
ret = new ArrayList<>();
|
||||
ret.add(array);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,738 @@
|
|||
package info.nightscout.androidaps.plugins.general.nsclient.services
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.*
|
||||
import androidx.work.OneTimeWorkRequest
|
||||
import com.google.common.base.Charsets
|
||||
import com.google.common.hash.Hashing
|
||||
import dagger.android.DaggerService
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.events.EventAppExit
|
||||
import info.nightscout.androidaps.events.EventConfigBuilderChange
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.interfaces.DataSyncSelector
|
||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.food.FoodPlugin.FoodWorker
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.*
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.acks.NSAddAck
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.acks.NSAuthAck
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.acks.NSUpdateAck
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.source.NSClientSourcePlugin.NSClientSourceWorker
|
||||
import info.nightscout.androidaps.receivers.DataWorker
|
||||
import info.nightscout.androidaps.services.Intents
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetLong
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetStringAllowNull
|
||||
import info.nightscout.androidaps.utils.T.Companion.days
|
||||
import info.nightscout.androidaps.utils.T.Companion.mins
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.socket.client.IO
|
||||
import io.socket.client.Socket
|
||||
import io.socket.emitter.Emitter
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.net.URISyntaxException
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class NSClientService : DaggerService() {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var nsSettingsStatus: NSSettingsStatus
|
||||
@Inject lateinit var nsDeviceStatus: NSDeviceStatus
|
||||
@Inject lateinit var databaseHelper: DatabaseHelperInterface
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var nsClientPlugin: NSClientPlugin
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorker: DataWorker
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var repository: AppRepository
|
||||
|
||||
companion object {
|
||||
private const val WATCHDOG_INTERVAL_MINUTES = 2
|
||||
private const val WATCHDOG_RECONNECT_IN = 15
|
||||
private const val WATCHDOG_MAX_CONNECTIONS = 5
|
||||
}
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
// public PowerManager.WakeLock mWakeLock;
|
||||
private val binder: IBinder = LocalBinder()
|
||||
private var handler: Handler? = null
|
||||
private var socket: Socket? = null
|
||||
private var dataCounter = 0
|
||||
private var connectCounter = 0
|
||||
private var nsEnabled = false
|
||||
private var nsAPISecret = ""
|
||||
private var nsDevice = ""
|
||||
private val nsHours = 48
|
||||
private var lastAckTime: Long = 0
|
||||
private var nsApiHashCode = ""
|
||||
private val reconnections = ArrayList<Long>()
|
||||
|
||||
var isConnected = false
|
||||
var hasWriteAuth = false
|
||||
var nsURL = ""
|
||||
var latestDateInReceivedData: Long = 0
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
// PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
// mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:NSClientService");
|
||||
// mWakeLock.acquire();
|
||||
initialize()
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventConfigBuilderChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({
|
||||
if (nsEnabled != nsClientPlugin.isEnabled(PluginType.GENERAL)) {
|
||||
latestDateInReceivedData = 0
|
||||
destroy()
|
||||
initialize()
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ event: EventPreferenceChange ->
|
||||
if (event.isChanged(resourceHelper, R.string.key_nsclientinternal_url) ||
|
||||
event.isChanged(resourceHelper, R.string.key_nsclientinternal_api_secret) ||
|
||||
event.isChanged(resourceHelper, R.string.key_nsclientinternal_paused)) {
|
||||
latestDateInReceivedData = 0
|
||||
destroy()
|
||||
initialize()
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventAppExit::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({
|
||||
aapsLogger.debug(LTag.NSCLIENT, "EventAppExit received")
|
||||
destroy()
|
||||
stopSelf()
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventNSClientRestart::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({
|
||||
latestDateInReceivedData = 0
|
||||
restart()
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(NSAuthAck::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ack -> processAuthAck(ack) }, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(NSUpdateAck::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ack -> processUpdateAck(ack) }, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(NSAddAck::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ack -> processAddAck(ack) }, fabricPrivacy::logException)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
disposable.clear()
|
||||
// if (mWakeLock.isHeld()) mWakeLock.release();
|
||||
}
|
||||
|
||||
private fun processAddAck(ack: NSAddAck) {
|
||||
lastAckTime = dateUtil.now()
|
||||
dataWorker.enqueue(
|
||||
OneTimeWorkRequest.Builder(NSClientAddAckWorker::class.java)
|
||||
.setInputData(dataWorker.storeInputData(ack, null))
|
||||
.build())
|
||||
}
|
||||
|
||||
private fun processUpdateAck(ack: NSUpdateAck) {
|
||||
lastAckTime = dateUtil.now()
|
||||
dataWorker.enqueue(
|
||||
OneTimeWorkRequest.Builder(NSClientUpdateRemoveAckWorker::class.java)
|
||||
.setInputData(dataWorker.storeInputData(ack, null))
|
||||
.build())
|
||||
}
|
||||
|
||||
fun processAuthAck(ack: NSAuthAck) {
|
||||
var connectionStatus = "Authenticated ("
|
||||
if (ack.read) connectionStatus += "R"
|
||||
if (ack.write) connectionStatus += "W"
|
||||
if (ack.write_treatment) connectionStatus += "T"
|
||||
connectionStatus += ')'
|
||||
isConnected = true
|
||||
hasWriteAuth = ack.write && ack.write_treatment
|
||||
rxBus.send(EventNSClientStatus(connectionStatus))
|
||||
rxBus.send(EventNSClientNewLog("AUTH", connectionStatus))
|
||||
if (!ack.write) {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "Write permission not granted "))
|
||||
}
|
||||
if (!ack.write_treatment) {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "Write treatment permission not granted "))
|
||||
}
|
||||
if (!hasWriteAuth) {
|
||||
val noWritePerm = Notification(Notification.NSCLIENT_NO_WRITE_PERMISSION, resourceHelper.gs(R.string.nowritepermission), Notification.URGENT)
|
||||
rxBus.send(EventNewNotification(noWritePerm))
|
||||
} else {
|
||||
rxBus.send(EventDismissNotification(Notification.NSCLIENT_NO_WRITE_PERMISSION))
|
||||
}
|
||||
}
|
||||
|
||||
inner class LocalBinder : Binder() {
|
||||
|
||||
val serviceInstance: NSClientService
|
||||
get() = this@NSClientService
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder {
|
||||
return binder
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
fun initialize() {
|
||||
dataCounter = 0
|
||||
readPreferences()
|
||||
@Suppress("UnstableApiUsage", "DEPRECATION")
|
||||
if (nsAPISecret != "") nsApiHashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString()
|
||||
rxBus.send(EventNSClientStatus("Initializing"))
|
||||
if (!nsClientPlugin.isAllowed) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "not allowed"))
|
||||
rxBus.send(EventNSClientStatus("Not allowed"))
|
||||
} else if (nsClientPlugin.paused) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "paused"))
|
||||
rxBus.send(EventNSClientStatus("Paused"))
|
||||
} else if (!nsEnabled) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "disabled"))
|
||||
rxBus.send(EventNSClientStatus("Disabled"))
|
||||
} else if (nsURL != "" && (buildHelper.isEngineeringMode() || nsURL.toLowerCase(Locale.getDefault()).startsWith("https://"))) {
|
||||
try {
|
||||
rxBus.send(EventNSClientStatus("Connecting ..."))
|
||||
val opt = IO.Options()
|
||||
opt.forceNew = true
|
||||
opt.reconnection = true
|
||||
socket = IO.socket(nsURL, opt).also { socket ->
|
||||
socket.on(Socket.EVENT_CONNECT, onConnect)
|
||||
socket.on(Socket.EVENT_DISCONNECT, onDisconnect)
|
||||
socket.on(Socket.EVENT_ERROR, onError)
|
||||
socket.on(Socket.EVENT_CONNECT_ERROR, onError)
|
||||
socket.on(Socket.EVENT_CONNECT_TIMEOUT, onError)
|
||||
socket.on(Socket.EVENT_PING, onPing)
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "do connect"))
|
||||
socket.connect()
|
||||
socket.on("dataUpdate", onDataUpdate)
|
||||
socket.on("announcement", onAnnouncement)
|
||||
socket.on("alarm", onAlarm)
|
||||
socket.on("urgent_alarm", onUrgentAlarm)
|
||||
socket.on("clear_alarm", onClearAlarm)
|
||||
}
|
||||
} catch (e: URISyntaxException) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "Wrong URL syntax"))
|
||||
rxBus.send(EventNSClientStatus("Wrong URL syntax"))
|
||||
} catch (e: RuntimeException) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "Wrong URL syntax"))
|
||||
rxBus.send(EventNSClientStatus("Wrong URL syntax"))
|
||||
}
|
||||
} else if (nsURL.toLowerCase(Locale.getDefault()).startsWith("http://")) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "NS URL not encrypted"))
|
||||
rxBus.send(EventNSClientStatus("Not encrypted"))
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "No NS URL specified"))
|
||||
rxBus.send(EventNSClientStatus("Not configured"))
|
||||
}
|
||||
}
|
||||
|
||||
private val onConnect = Emitter.Listener {
|
||||
connectCounter++
|
||||
val socketId = socket?.id() ?: "NULL"
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "connect #$connectCounter event. ID: $socketId"))
|
||||
if (socket != null) sendAuthMessage(NSAuthAck(rxBus))
|
||||
watchdog()
|
||||
}
|
||||
|
||||
private fun watchdog() {
|
||||
synchronized(reconnections) {
|
||||
val now = dateUtil.now()
|
||||
reconnections.add(now)
|
||||
for (r in reconnections.reversed()) {
|
||||
if (r < now - mins(WATCHDOG_INTERVAL_MINUTES.toLong()).msecs()) {
|
||||
reconnections.remove(r)
|
||||
}
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " minutes: " + reconnections.size + "/" + WATCHDOG_MAX_CONNECTIONS))
|
||||
if (reconnections.size >= WATCHDOG_MAX_CONNECTIONS) {
|
||||
val n = Notification(Notification.NS_MALFUNCTION, resourceHelper.gs(R.string.nsmalfunction), Notification.URGENT)
|
||||
rxBus.send(EventNewNotification(n))
|
||||
rxBus.send(EventNSClientNewLog("WATCHDOG", "pausing for $WATCHDOG_RECONNECT_IN minutes"))
|
||||
nsClientPlugin.pause(true)
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
Thread {
|
||||
SystemClock.sleep(mins(WATCHDOG_RECONNECT_IN.toLong()).msecs())
|
||||
rxBus.send(EventNSClientNewLog("WATCHDOG", "re-enabling NSClient"))
|
||||
nsClientPlugin.pause(false)
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val onDisconnect = Emitter.Listener { args ->
|
||||
aapsLogger.debug(LTag.NSCLIENT, "disconnect reason: {}", *args)
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "disconnect event"))
|
||||
}
|
||||
|
||||
@Synchronized fun destroy() {
|
||||
socket?.off(Socket.EVENT_CONNECT)
|
||||
socket?.off(Socket.EVENT_DISCONNECT)
|
||||
socket?.off(Socket.EVENT_PING)
|
||||
socket?.off("dataUpdate")
|
||||
socket?.off("announcement")
|
||||
socket?.off("alarm")
|
||||
socket?.off("urgent_alarm")
|
||||
socket?.off("clear_alarm")
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "destroy"))
|
||||
isConnected = false
|
||||
hasWriteAuth = false
|
||||
socket?.disconnect()
|
||||
socket = null
|
||||
}
|
||||
|
||||
private fun sendAuthMessage(ack: NSAuthAck?) {
|
||||
val authMessage = JSONObject()
|
||||
try {
|
||||
authMessage.put("client", "Android_$nsDevice")
|
||||
authMessage.put("history", nsHours)
|
||||
authMessage.put("status", true) // receive status
|
||||
authMessage.put("from", latestDateInReceivedData) // send data newer than
|
||||
authMessage.put("secret", nsApiHashCode)
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
return
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("AUTH", "requesting auth"))
|
||||
socket?.emit("authorize", authMessage, ack)
|
||||
}
|
||||
|
||||
fun readPreferences() {
|
||||
nsEnabled = nsClientPlugin.isEnabled(PluginType.GENERAL)
|
||||
nsURL = sp.getString(R.string.key_nsclientinternal_url, "")
|
||||
nsAPISecret = sp.getString(R.string.key_nsclientinternal_api_secret, "")
|
||||
nsDevice = sp.getString("careportal_enteredby", "")
|
||||
}
|
||||
|
||||
private val onError = Emitter.Listener { args ->
|
||||
var msg = "Unknown Error"
|
||||
if (args.isNotEmpty() && args[0] != null) {
|
||||
msg = args[0].toString()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("ERROR", msg))
|
||||
}
|
||||
private val onPing = Emitter.Listener {
|
||||
rxBus.send(EventNSClientNewLog("PING", "received"))
|
||||
// send data if there is something waiting
|
||||
resend("Ping received")
|
||||
}
|
||||
private val onAnnouncement = Emitter.Listener { args ->
|
||||
|
||||
/*
|
||||
{
|
||||
"level":0,
|
||||
"title":"Announcement",
|
||||
"message":"test",
|
||||
"plugin":{"name":"treatmentnotify","label":"Treatment Notifications","pluginType":"notification","enabled":true},
|
||||
"group":"Announcement",
|
||||
"isAnnouncement":true,
|
||||
"key":"9ac46ad9a1dcda79dd87dae418fce0e7955c68da"
|
||||
}
|
||||
*/
|
||||
val data: JSONObject
|
||||
try {
|
||||
data = args[0] as JSONObject
|
||||
handleAnnouncement(data)
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
}
|
||||
private val onAlarm = Emitter.Listener { args ->
|
||||
|
||||
/*
|
||||
{
|
||||
"level":1,
|
||||
"title":"Warning HIGH",
|
||||
"message":"BG Now: 5 -0.2 → mmol\/L\nRaw BG: 4.8 mmol\/L Čistý\nBG 15m: 4.8 mmol\/L\nIOB: -0.02U\nCOB: 0g",
|
||||
"eventName":"high",
|
||||
"plugin":{"name":"simplealarms","label":"Simple Alarms","pluginType":"notification","enabled":true},
|
||||
"pushoverSound":"climb",
|
||||
"debug":{"lastSGV":5,"thresholds":{"bgHigh":180,"bgTargetTop":75,"bgTargetBottom":72,"bgLow":70}},
|
||||
"group":"default",
|
||||
"key":"simplealarms_1"
|
||||
}
|
||||
*/
|
||||
val data: JSONObject
|
||||
try {
|
||||
data = args[0] as JSONObject
|
||||
handleAlarm(data)
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
}
|
||||
private val onUrgentAlarm = Emitter.Listener { args: Array<Any> ->
|
||||
val data: JSONObject
|
||||
try {
|
||||
data = args[0] as JSONObject
|
||||
handleUrgentAlarm(data)
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
}
|
||||
private val onClearAlarm = Emitter.Listener { args ->
|
||||
|
||||
/*
|
||||
{
|
||||
"clear":true,
|
||||
"title":"All Clear",
|
||||
"message":"default - Urgent was ack'd",
|
||||
"group":"default"
|
||||
}
|
||||
*/
|
||||
val data: JSONObject
|
||||
try {
|
||||
data = args[0] as JSONObject
|
||||
rxBus.send(EventNSClientNewLog("CLEARALARM", "received"))
|
||||
rxBus.send(EventDismissNotification(Notification.NS_ALARM))
|
||||
rxBus.send(EventDismissNotification(Notification.NS_URGENT_ALARM))
|
||||
aapsLogger.debug(LTag.NSCLIENT, data.toString())
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
}
|
||||
private val onDataUpdate = Emitter.Listener { args ->
|
||||
handler?.post {
|
||||
val powerManager = getSystemService(POWER_SERVICE) as PowerManager
|
||||
val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||
"AndroidAPS:NSClientService_onDataUpdate")
|
||||
wakeLock.acquire(3000)
|
||||
try {
|
||||
val data = args[0] as JSONObject
|
||||
try {
|
||||
// delta means only increment/changes are coming
|
||||
val isDelta = data.has("delta")
|
||||
rxBus.send(EventNSClientNewLog("DATA", "Data packet #" + dataCounter++ + if (isDelta) " delta" else " full"))
|
||||
if (data.has("status")) {
|
||||
val status = data.getJSONObject("status")
|
||||
nsSettingsStatus.handleNewData(status)
|
||||
} else if (!isDelta) {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "Unsupported Nightscout version "))
|
||||
}
|
||||
if (data.has("profiles")) {
|
||||
val profiles = data.getJSONArray("profiles")
|
||||
if (profiles.length() > 0) {
|
||||
// take the newest
|
||||
val profileStoreJson = profiles[profiles.length() - 1] as JSONObject
|
||||
rxBus.send(EventNSClientNewLog("PROFILE", "profile received"))
|
||||
dataWorker.enqueue(
|
||||
OneTimeWorkRequest.Builder(LocalProfilePlugin.NSProfileWorker::class.java)
|
||||
.setInputData(dataWorker.storeInputData(profileStoreJson, null))
|
||||
.build())
|
||||
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("profile", profileStoreJson.toString())
|
||||
bundle.putBoolean("delta", isDelta)
|
||||
val intent = Intent(Intents.ACTION_NEW_PROFILE)
|
||||
intent.putExtras(bundle)
|
||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.has("treatments")) {
|
||||
val treatments = data.getJSONArray("treatments")
|
||||
val removedTreatments = JSONArray()
|
||||
val addedOrUpdatedTreatments = JSONArray()
|
||||
if (treatments.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + treatments.length() + " treatments"))
|
||||
for (index in 0 until treatments.length()) {
|
||||
val jsonTreatment = treatments.getJSONObject(index)
|
||||
val action = safeGetStringAllowNull(jsonTreatment, "action", null)
|
||||
val mills = safeGetLong(jsonTreatment, "mills")
|
||||
if (action == null) addedOrUpdatedTreatments.put(jsonTreatment) else if (action == "update") addedOrUpdatedTreatments.put(jsonTreatment) else if (action == "remove" && mills > dateUtil.now() - days(1).msecs()) // handle 1 day old deletions only
|
||||
removedTreatments.put(jsonTreatment)
|
||||
}
|
||||
if (removedTreatments.length() > 0) {
|
||||
dataWorker.enqueue(
|
||||
OneTimeWorkRequest.Builder(NSClientRemoveWorker::class.java)
|
||||
.setInputData(dataWorker.storeInputData(removedTreatments, null))
|
||||
.build())
|
||||
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("treatments", removedTreatments.toString())
|
||||
bundle.putBoolean("delta", isDelta)
|
||||
val intent = Intent(Intents.ACTION_REMOVED_TREATMENT)
|
||||
intent.putExtras(bundle)
|
||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
}
|
||||
if (addedOrUpdatedTreatments.length() > 0) {
|
||||
dataWorker.enqueue(
|
||||
OneTimeWorkRequest.Builder(NSClientAddUpdateWorker::class.java)
|
||||
.setInputData(dataWorker.storeInputData(addedOrUpdatedTreatments, null))
|
||||
.build())
|
||||
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
|
||||
val splitted = splitArray(addedOrUpdatedTreatments)
|
||||
for (part in splitted) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("treatments", part.toString())
|
||||
bundle.putBoolean("delta", isDelta)
|
||||
val intent = Intent(Intents.ACTION_CHANGED_TREATMENT)
|
||||
intent.putExtras(bundle)
|
||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.has("devicestatus")) {
|
||||
val devicestatuses = data.getJSONArray("devicestatus")
|
||||
if (devicestatuses.length() > 0) {
|
||||
rxBus.send(EventNSClientNewLog("DATA", "received " + devicestatuses.length() + " device statuses"))
|
||||
nsDeviceStatus.handleNewData(devicestatuses)
|
||||
}
|
||||
}
|
||||
if (data.has("food")) {
|
||||
val foods = data.getJSONArray("food")
|
||||
if (foods.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + foods.length() + " foods"))
|
||||
dataWorker.enqueue(
|
||||
OneTimeWorkRequest.Builder(FoodWorker::class.java)
|
||||
.setInputData(dataWorker.storeInputData(foods, null))
|
||||
.build())
|
||||
}
|
||||
if (data.has("mbgs")) {
|
||||
val mbgArray = data.getJSONArray("mbgs")
|
||||
if (mbgArray.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + mbgArray.length() + " mbgs"))
|
||||
dataWorker.enqueue(
|
||||
OneTimeWorkRequest.Builder(NSClientMbgWorker::class.java)
|
||||
.setInputData(dataWorker.storeInputData(mbgArray, null))
|
||||
.build())
|
||||
}
|
||||
if (data.has("cals")) {
|
||||
val cals = data.getJSONArray("cals")
|
||||
if (cals.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + cals.length() + " cals"))
|
||||
// Calibrations ignored
|
||||
}
|
||||
if (data.has("sgvs")) {
|
||||
val sgvs = data.getJSONArray("sgvs")
|
||||
if (sgvs.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + sgvs.length() + " sgvs"))
|
||||
dataWorker.enqueue(OneTimeWorkRequest.Builder(NSClientSourceWorker::class.java)
|
||||
.setInputData(dataWorker.storeInputData(sgvs, null))
|
||||
.build())
|
||||
val splitted = splitArray(sgvs)
|
||||
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
|
||||
for (part in splitted) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("sgvs", part.toString())
|
||||
bundle.putBoolean("delta", isDelta)
|
||||
val intent = Intent(Intents.ACTION_NEW_SGV)
|
||||
intent.putExtras(bundle)
|
||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("LAST", dateUtil.dateAndTimeString(latestDateInReceivedData)))
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
//rxBus.send(new EventNSClientNewLog("NSCLIENT", "onDataUpdate end");
|
||||
} finally {
|
||||
if (wakeLock.isHeld) wakeLock.release()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun dbUpdate(collection: String, _id: String?, data: JSONObject?, originalObject: Any) {
|
||||
try {
|
||||
if (_id == null) return
|
||||
if (!isConnected || !hasWriteAuth) return
|
||||
val message = JSONObject()
|
||||
message.put("collection", collection)
|
||||
message.put("_id", _id)
|
||||
message.put("data", data)
|
||||
socket?.emit("dbUpdate", message, NSUpdateAck("dbUpdate", _id, aapsLogger, rxBus, originalObject))
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE $collection", "Sent " + originalObject.javaClass.simpleName + " " + _id))
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
}
|
||||
|
||||
fun dbRemove(collection: String, _id: String?, originalObject: Any) {
|
||||
try {
|
||||
if (_id == null) return
|
||||
if (!isConnected || !hasWriteAuth) return
|
||||
val message = JSONObject()
|
||||
message.put("collection", collection)
|
||||
message.put("_id", _id)
|
||||
socket?.emit("dbRemove", message, NSUpdateAck("dbRemove", _id, aapsLogger, rxBus, originalObject))
|
||||
rxBus.send(EventNSClientNewLog("DBREMOVE $collection", "Sent " + originalObject.javaClass.simpleName + " " + _id))
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
}
|
||||
|
||||
fun dbAdd(collection: String, data: JSONObject, originalObject: Any) {
|
||||
try {
|
||||
if (!isConnected || !hasWriteAuth) return
|
||||
val message = JSONObject()
|
||||
message.put("collection", collection)
|
||||
message.put("data", data)
|
||||
socket?.emit("dbAdd", message, NSAddAck(aapsLogger, rxBus, originalObject))
|
||||
rxBus.send(EventNSClientNewLog("DBADD $collection", "Sent " + originalObject.javaClass.simpleName + " " + data))
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
}
|
||||
|
||||
fun sendAlarmAck(alarmAck: AlarmAck) {
|
||||
if (!isConnected || !hasWriteAuth) return
|
||||
socket?.emit("ack", alarmAck.level, alarmAck.group, alarmAck.silenceTime)
|
||||
rxBus.send(EventNSClientNewLog("ALARMACK ", alarmAck.level.toString() + " " + alarmAck.group + " " + alarmAck.silenceTime))
|
||||
}
|
||||
|
||||
fun resend(reason: String) {
|
||||
if (!isConnected || !hasWriteAuth) return
|
||||
handler?.post {
|
||||
if (socket?.connected() != true) return@post
|
||||
if (lastAckTime > System.currentTimeMillis() - 10 * 1000L) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Skipping resend by lastAckTime: " + (System.currentTimeMillis() - lastAckTime) / 1000L + " sec")
|
||||
return@post
|
||||
}
|
||||
val powerManager = getSystemService(POWER_SERVICE) as PowerManager
|
||||
val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||
"AndroidAPS:NSClientService_onDataUpdate")
|
||||
wakeLock.acquire(mins(10).msecs())
|
||||
try {
|
||||
rxBus.send(EventNSClientNewLog("QUEUE", "Resend started: $reason"))
|
||||
dataSyncSelector.doUpload()
|
||||
rxBus.send(EventNSClientNewLog("QUEUE", "Resend ended: $reason"))
|
||||
} finally {
|
||||
if (wakeLock.isHeld) wakeLock.release()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun restart() {
|
||||
destroy()
|
||||
initialize()
|
||||
}
|
||||
|
||||
private fun handleAnnouncement(announcement: JSONObject) {
|
||||
val defaultVal = config.NSCLIENT
|
||||
if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) {
|
||||
val nsAlarm = NSAlarm(announcement)
|
||||
val notification: Notification = NotificationWithAction(injector, nsAlarm)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
rxBus.send(EventNSClientNewLog("ANNOUNCEMENT", safeGetString(announcement, "message", "received")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, announcement.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleAlarm(alarm: JSONObject) {
|
||||
val defaultVal = config.NSCLIENT
|
||||
if (sp.getBoolean(R.string.key_ns_alarms, defaultVal)) {
|
||||
val snoozedTo = sp.getLong(R.string.key_snoozedTo, 0L)
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
|
||||
val nsAlarm = NSAlarm(alarm)
|
||||
val notification: Notification = NotificationWithAction(injector, nsAlarm)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("ALARM", safeGetString(alarm, "message", "received")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, alarm.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleUrgentAlarm(alarm: JSONObject) {
|
||||
val defaultVal = config.NSCLIENT
|
||||
if (sp.getBoolean(R.string.key_ns_alarms, defaultVal)) {
|
||||
val snoozedTo = sp.getLong(R.string.key_snoozedTo, 0L)
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
|
||||
val nsAlarm = NSAlarm(alarm)
|
||||
val notification: Notification = NotificationWithAction(injector, nsAlarm)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("URGENTALARM", safeGetString(alarm, "message", "received")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, alarm.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun splitArray(array: JSONArray): List<JSONArray> {
|
||||
var ret: MutableList<JSONArray> = ArrayList()
|
||||
try {
|
||||
val size = array.length()
|
||||
var count = 0
|
||||
var newarr: JSONArray? = null
|
||||
for (i in 0 until size) {
|
||||
if (count == 0) {
|
||||
if (newarr != null) ret.add(newarr)
|
||||
newarr = JSONArray()
|
||||
count = 20
|
||||
}
|
||||
newarr?.put(array[i])
|
||||
--count
|
||||
}
|
||||
if (newarr != null && newarr.length() > 0) ret.add(newarr)
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
ret = ArrayList()
|
||||
ret.add(array)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
init {
|
||||
if (handler == null) {
|
||||
val handlerThread = HandlerThread(NSClientService::class.java.simpleName + "Handler")
|
||||
handlerThread.start()
|
||||
handler = Handler(handlerThread.looper)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -178,24 +178,24 @@ class OpenHumansUploader @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun enqueueTreatment(treatment: Treatment?, deleted: Boolean = false) = treatment?.let {
|
||||
insertQueueItem("Treatments") {
|
||||
put("date", treatment.date)
|
||||
put("isValid", treatment.isValid)
|
||||
put("source", treatment.source)
|
||||
put("nsId", treatment._id)
|
||||
put("boluscalc", treatment.boluscalc)
|
||||
put("carbs", treatment.carbs)
|
||||
put("dia", treatment.dia)
|
||||
put("insulin", treatment.insulin)
|
||||
put("insulinInterfaceID", treatment.insulinInterfaceID)
|
||||
put("isSMB", treatment.isSMB)
|
||||
put("mealBolus", treatment.mealBolus)
|
||||
put("bolusCalcJson", treatment.getBoluscalc())
|
||||
put("isDeletion", deleted)
|
||||
}
|
||||
}
|
||||
// @JvmOverloads
|
||||
// fun enqueueTreatment(treatment: Treatment?, deleted: Boolean = false) = treatment?.let {
|
||||
// insertQueueItem("Treatments") {
|
||||
// put("date", treatment.date)
|
||||
// put("isValid", treatment.isValid)
|
||||
// put("source", treatment.source)
|
||||
// put("nsId", treatment._id)
|
||||
// put("boluscalc", treatment.boluscalc)
|
||||
// put("carbs", treatment.carbs)
|
||||
// put("dia", treatment.dia)
|
||||
// put("insulin", treatment.insulin)
|
||||
// put("insulinInterfaceID", treatment.insulinInterfaceID)
|
||||
// put("isSMB", treatment.isSMB)
|
||||
// put("mealBolus", treatment.mealBolus)
|
||||
// put("bolusCalcJson", treatment.getBoluscalc())
|
||||
// put("isDeletion", deleted)
|
||||
// }
|
||||
// }
|
||||
|
||||
@JvmOverloads
|
||||
fun enqueueTherapyEvent(therapyEvent: TherapyEvent, deleted: Boolean = false) = insertQueueItem("TherapyEvents") {
|
||||
|
@ -210,17 +210,17 @@ class OpenHumansUploader @Inject constructor(
|
|||
put("isDeletion", deleted)
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun enqueueExtendedBolus(extendedBolus: ExtendedBolus, deleted: Boolean = false) = insertQueueItem("ExtendedBoluses") {
|
||||
put("date", extendedBolus.date)
|
||||
put("isValid", extendedBolus.isValid)
|
||||
put("source", extendedBolus.source)
|
||||
put("nsId", extendedBolus._id)
|
||||
put("pumpId", extendedBolus.pumpId)
|
||||
put("insulin", extendedBolus.insulin)
|
||||
put("durationInMinutes", extendedBolus.durationInMinutes)
|
||||
put("isDeletion", deleted)
|
||||
}
|
||||
// @JvmOverloads
|
||||
// fun enqueueExtendedBolus(extendedBolus: ExtendedBolus, deleted: Boolean = false) = insertQueueItem("ExtendedBoluses") {
|
||||
// put("date", extendedBolus.date)
|
||||
// put("isValid", extendedBolus.isValid)
|
||||
// put("source", extendedBolus.source)
|
||||
// put("nsId", extendedBolus._id)
|
||||
// put("pumpId", extendedBolus.pumpId)
|
||||
// put("insulin", extendedBolus.insulin)
|
||||
// put("durationInMinutes", extendedBolus.durationInMinutes)
|
||||
// put("isDeletion", deleted)
|
||||
// }
|
||||
|
||||
// @JvmOverloads
|
||||
// fun enqueueProfileSwitch(profileSwitch: ProfileSwitch, deleted: Boolean = false) = insertQueueItem("ProfileSwitches") {
|
||||
|
@ -244,22 +244,22 @@ class OpenHumansUploader @Inject constructor(
|
|||
// put("double", tdd.total)
|
||||
// }
|
||||
|
||||
@JvmOverloads
|
||||
fun enqueueTemporaryBasal(temporaryBasal: TemporaryBasal?, deleted: Boolean = false) = temporaryBasal?.let {
|
||||
insertQueueItem("TemporaryBasals") {
|
||||
put("date", temporaryBasal.date)
|
||||
put("isValid", temporaryBasal.isValid)
|
||||
put("source", temporaryBasal.source)
|
||||
put("nsId", temporaryBasal._id)
|
||||
put("pumpId", temporaryBasal.pumpId)
|
||||
put("durationInMinutes", temporaryBasal.durationInMinutes)
|
||||
put("durationInMinutes", temporaryBasal.durationInMinutes)
|
||||
put("isAbsolute", temporaryBasal.isAbsolute)
|
||||
put("percentRate", temporaryBasal.percentRate)
|
||||
put("absoluteRate", temporaryBasal.absoluteRate)
|
||||
put("isDeletion", deleted)
|
||||
}
|
||||
}
|
||||
// @JvmOverloads
|
||||
// fun enqueueTemporaryBasal(temporaryBasal: TemporaryBasal?, deleted: Boolean = false) = temporaryBasal?.let {
|
||||
// insertQueueItem("TemporaryBasals") {
|
||||
// put("date", temporaryBasal.date)
|
||||
// put("isValid", temporaryBasal.isValid)
|
||||
// put("source", temporaryBasal.source)
|
||||
// put("nsId", temporaryBasal._id)
|
||||
// put("pumpId", temporaryBasal.pumpId)
|
||||
// put("durationInMinutes", temporaryBasal.durationInMinutes)
|
||||
// put("durationInMinutes", temporaryBasal.durationInMinutes)
|
||||
// put("isAbsolute", temporaryBasal.isAbsolute)
|
||||
// put("percentRate", temporaryBasal.percentRate)
|
||||
// put("absoluteRate", temporaryBasal.absoluteRate)
|
||||
// put("isDeletion", deleted)
|
||||
// }
|
||||
// }
|
||||
|
||||
@JvmOverloads
|
||||
fun enqueueTempTarget(tempTarget: TemporaryTarget?, deleted: Boolean = false) = tempTarget?.let {
|
||||
|
|
|
@ -10,6 +10,7 @@ import android.graphics.Paint
|
|||
import android.graphics.drawable.AnimationDrawable
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -24,10 +25,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||
import com.jjoe64.graphview.GraphView
|
||||
import dagger.android.HasAndroidInjector
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.ValueWrapper
|
||||
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
||||
|
@ -124,7 +123,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
private lateinit var dm: DisplayMetrics
|
||||
private var axisWidth: Int = 0
|
||||
private var rangeToDisplay = 6 // for graph
|
||||
private var loopHandler = Handler()
|
||||
private lateinit var loopHandler: Handler
|
||||
private var refreshLoop: Runnable? = null
|
||||
|
||||
private val secondaryGraphs = ArrayList<GraphView>()
|
||||
|
@ -150,6 +149,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
loopHandler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
|
||||
|
||||
// pre-process landscape mode
|
||||
val screenWidth = dm.widthPixels
|
||||
|
@ -297,14 +297,14 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
if (childFragmentManager.isStateSaved) return
|
||||
activity?.let { activity ->
|
||||
when (v.id) {
|
||||
R.id.treatment_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) TreatmentDialog().show(childFragmentManager, "Overview") })
|
||||
R.id.wizard_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) WizardDialog().show(childFragmentManager, "Overview") })
|
||||
R.id.insulin_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) InsulinDialog().show(childFragmentManager, "Overview") })
|
||||
R.id.treatment_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) TreatmentDialog().show(childFragmentManager, "Overview") })
|
||||
R.id.wizard_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) WizardDialog().show(childFragmentManager, "Overview") })
|
||||
R.id.insulin_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) InsulinDialog().show(childFragmentManager, "Overview") })
|
||||
R.id.quick_wizard_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) onClickQuickWizard() })
|
||||
R.id.carbs_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) CarbsDialog().show(childFragmentManager, "Overview") })
|
||||
R.id.temp_target -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) TempTargetDialog().show(childFragmentManager, "Overview") })
|
||||
R.id.carbs_button -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) CarbsDialog().show(childFragmentManager, "Overview") })
|
||||
R.id.temp_target -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { if (isAdded) TempTargetDialog().show(childFragmentManager, "Overview") })
|
||||
|
||||
R.id.active_profile -> {
|
||||
R.id.active_profile -> {
|
||||
ProfileViewerDialog().also { pvd ->
|
||||
pvd.arguments = Bundle().also {
|
||||
it.putLong("time", dateUtil.now())
|
||||
|
@ -313,7 +313,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
}.show(childFragmentManager, "ProfileViewDialog")
|
||||
}
|
||||
|
||||
R.id.cgm_button -> {
|
||||
R.id.cgm_button -> {
|
||||
if (xdripPlugin.isEnabled(PluginType.BGSOURCE))
|
||||
openCgmApp("com.eveningoutpost.dexdrip")
|
||||
else if (dexcomPlugin.isEnabled(PluginType.BGSOURCE)) {
|
||||
|
@ -324,7 +324,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
}
|
||||
}
|
||||
|
||||
R.id.calibration_button -> {
|
||||
R.id.calibration_button -> {
|
||||
if (xdripPlugin.isEnabled(PluginType.BGSOURCE)) {
|
||||
CalibrationDialog().show(childFragmentManager, "CalibrationDialog")
|
||||
} else if (dexcomPlugin.isEnabled(PluginType.BGSOURCE)) {
|
||||
|
@ -339,27 +339,29 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
}
|
||||
}
|
||||
|
||||
R.id.accept_temp_button -> {
|
||||
R.id.accept_temp_button -> {
|
||||
profileFunction.getProfile() ?: return
|
||||
if (loopPlugin.isEnabled(PluginType.LOOP)) {
|
||||
val lastRun = loopPlugin.lastRun
|
||||
loopPlugin.invoke("Accept temp button", false)
|
||||
if (lastRun?.lastAPSRun != null && lastRun.constraintsProcessed?.isChangeRequested == true) {
|
||||
protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable {
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.tempbasal_label), lastRun.constraintsProcessed?.toSpanned()
|
||||
?: "".toSpanned(), {
|
||||
uel.log(Action.ACCEPTS_TEMP_BASAL, Sources.Overview)
|
||||
binding.buttonsLayout.acceptTempButton.visibility = View.GONE
|
||||
(context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).cancel(Constants.notificationID)
|
||||
rxBus.send(EventWearInitiateAction("cancelChangeRequest"))
|
||||
loopPlugin.acceptChangeRequest()
|
||||
loopHandler.post {
|
||||
val lastRun = loopPlugin.lastRun
|
||||
loopPlugin.invoke("Accept temp button", false)
|
||||
if (lastRun?.lastAPSRun != null && lastRun.constraintsProcessed?.isChangeRequested == true) {
|
||||
protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable {
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.tempbasal_label), lastRun.constraintsProcessed?.toSpanned()
|
||||
?: "".toSpanned(), {
|
||||
uel.log(Action.ACCEPTS_TEMP_BASAL, Sources.Overview)
|
||||
binding.buttonsLayout.acceptTempButton.visibility = View.GONE
|
||||
(context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).cancel(Constants.notificationID)
|
||||
rxBus.send(EventWearInitiateAction("cancelChangeRequest"))
|
||||
Thread { loopPlugin.acceptChangeRequest() }.run()
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R.id.aps_mode -> {
|
||||
R.id.aps_mode -> {
|
||||
protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable {
|
||||
if (isAdded) LoopDialog().also { dialog ->
|
||||
dialog.arguments = Bundle().also { it.putInt("showOkCancel", 1) }
|
||||
|
@ -391,7 +393,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
return true
|
||||
}
|
||||
|
||||
R.id.aps_mode -> {
|
||||
R.id.aps_mode -> {
|
||||
activity?.let { activity ->
|
||||
protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable {
|
||||
LoopDialog().also { dialog ->
|
||||
|
@ -401,8 +403,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
}
|
||||
}
|
||||
|
||||
R.id.temp_target -> v.performClick()
|
||||
R.id.active_profile -> activity?.let { activity -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { ProfileSwitchDialog().show(childFragmentManager, "Overview") }) }
|
||||
R.id.temp_target -> v.performClick()
|
||||
R.id.active_profile -> activity?.let { activity -> protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, UIRunnable { ProfileSwitchDialog().show(childFragmentManager, "Overview") }) }
|
||||
|
||||
}
|
||||
return false
|
||||
|
@ -775,7 +777,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
if (config.APS && lastRun?.constraintsProcessed != null) {
|
||||
if (lastRun.constraintsProcessed!!.carbsReq > 0) {
|
||||
//only display carbsreq when carbs have not been entered recently
|
||||
val lastCarb = repository.getLastCarbsRecordWrapped().blockingGet()
|
||||
val lastCarb = repository.getLastCarbsRecordWrapped().blockingGet()
|
||||
val lastCarbsTime = if (lastCarb is ValueWrapper.Existing) lastCarb.value.timestamp else 0L
|
||||
if (lastCarbsTime < lastRun.lastAPSRun) {
|
||||
cobText = cobText + " | " + lastRun.constraintsProcessed!!.carbsReq + " " + resourceHelper.gs(R.string.required)
|
||||
|
@ -860,7 +862,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
|
||||
// **** BG ****
|
||||
if (predictionsAvailable && menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal])
|
||||
graphData.addBgReadings(fromTime, toTime, highLine, apsResult?.predictions?.map { bg-> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, resourceHelper) }?.toMutableList())
|
||||
graphData.addBgReadings(fromTime, toTime, highLine, apsResult?.predictions?.map { bg -> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, resourceHelper) }?.toMutableList())
|
||||
else graphData.addBgReadings(fromTime, toTime, highLine, null)
|
||||
if (buildHelper.isDev()) graphData.addBucketedData(fromTime, toTime)
|
||||
|
||||
|
|
|
@ -400,9 +400,8 @@ class GraphData(
|
|||
time += 5 * 60 * 1000L
|
||||
continue
|
||||
}
|
||||
var iob = 0.0
|
||||
var absIob = 0.0
|
||||
iob = iobCobCalculator.calculateFromTreatmentsAndTemps(time, profile).iob
|
||||
val iob: Double = iobCobCalculator.calculateFromTreatmentsAndTemps(time, profile).iob
|
||||
if (absScale) absIob = iobCobCalculator.calculateAbsInsulinFromTreatmentsAndTemps(time).iob
|
||||
if (abs(lastIob - iob) > 0.02) {
|
||||
if (abs(lastIob - iob) > 0.2) iobArray.add(ScaledDataPoint(time, lastIob, iobScale))
|
||||
|
@ -461,8 +460,7 @@ class GraphData(
|
|||
time += 5 * 60 * 1000L
|
||||
continue
|
||||
}
|
||||
var iob = 0.0
|
||||
iob = iobCobCalculator.calculateAbsInsulinFromTreatmentsAndTemps(time).iob
|
||||
val iob: Double = iobCobCalculator.calculateAbsInsulinFromTreatmentsAndTemps(time).iob
|
||||
if (abs(lastIob - iob) > 0.02) {
|
||||
if (abs(lastIob - iob) > 0.2) iobArray.add(ScaledDataPoint(time, lastIob, iobScale))
|
||||
iobArray.add(ScaledDataPoint(time, iob, iobScale))
|
||||
|
|
|
@ -54,6 +54,9 @@ class LocalProfileFragment : DaggerFragment() {
|
|||
private val save = Runnable {
|
||||
doEdit()
|
||||
basalView?.updateLabel(resourceHelper.gs(R.string.basal_label) + ": " + sumLabel())
|
||||
localProfilePlugin.profile?.getSpecificProfile(spinner?.selectedItem.toString())?.let {
|
||||
binding.basalGraph.show(ProfileSealed.Pure(it))
|
||||
}
|
||||
}
|
||||
|
||||
private val textWatch = object : TextWatcher {
|
||||
|
@ -124,7 +127,7 @@ class LocalProfileFragment : DaggerFragment() {
|
|||
binding.dia.setParams(currentProfile.dia, hardLimits.minDia(), hardLimits.maxDia(), 0.1, DecimalFormat("0.0"), false, binding.save, textWatch)
|
||||
binding.dia.tag = "LP_DIA"
|
||||
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.ic, "IC", resourceHelper.gs(R.string.ic_label), currentProfile.ic, null, hardLimits.minIC(), hardLimits.maxIC(), 0.1, DecimalFormat("0.0"), save)
|
||||
basalView = TimeListEdit(context, aapsLogger, dateUtil, view, R.id.basal, "BASAL", resourceHelper.gs(R.string.basal_label) + ": " + sumLabel(), currentProfile.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save)
|
||||
basalView = TimeListEdit(context, aapsLogger, dateUtil, view, R.id.basal_holder, "BASAL", resourceHelper.gs(R.string.basal_label) + ": " + sumLabel(), currentProfile.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save)
|
||||
if (units == Constants.MGDL) {
|
||||
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, HardLimits.MIN_ISF, HardLimits.MAX_ISF, 1.0, DecimalFormat("0"), save)
|
||||
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), 1.0, DecimalFormat("0"), save)
|
||||
|
@ -162,6 +165,9 @@ class LocalProfileFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
})
|
||||
localProfilePlugin.profile?.getSpecificProfile(spinner?.selectedItem.toString())?.let {
|
||||
binding.basalGraph.show(ProfileSealed.Pure(it))
|
||||
}
|
||||
|
||||
binding.profileAdd.setOnClickListener {
|
||||
if (localProfilePlugin.isEdited) {
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package info.nightscout.androidaps.plugins.profile.local
|
||||
|
||||
import android.content.Context
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
|
@ -12,7 +16,8 @@ import info.nightscout.androidaps.interfaces.*
|
|||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
|
||||
import info.nightscout.androidaps.receivers.DataWorker
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.HardLimits
|
||||
|
@ -35,7 +40,6 @@ class LocalProfilePlugin @Inject constructor(
|
|||
resourceHelper: ResourceHelper,
|
||||
private val sp: SP,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val nsUpload: NSUpload,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val hardLimits: HardLimits,
|
||||
private val dateUtil: DateUtil
|
||||
|
@ -144,7 +148,7 @@ class LocalProfilePlugin @Inject constructor(
|
|||
if (name.contains(".")) namesOK = false
|
||||
}
|
||||
if (namesOK)
|
||||
rawProfile?.let { nsUpload.uploadProfileStore(it.data) }
|
||||
sp.putLong(R.string.key_local_profile_last_change, dateUtil.now())
|
||||
else
|
||||
activity?.let {
|
||||
OKDialog.show(it, "", resourceHelper.gs(R.string.profilenamecontainsdot))
|
||||
|
@ -167,61 +171,64 @@ class LocalProfilePlugin @Inject constructor(
|
|||
p.dia = sp.getDouble(localProfileNumbered + "dia", Constants.defaultDIA)
|
||||
try {
|
||||
p.ic = JSONArray(sp.getString(localProfileNumbered + "ic", defaultArray))
|
||||
} catch (e1: JSONException) {
|
||||
try {
|
||||
p.ic = JSONArray(defaultArray)
|
||||
} catch (ignored: JSONException) {
|
||||
}
|
||||
aapsLogger.error("Exception", e1)
|
||||
}
|
||||
|
||||
try {
|
||||
p.isf = JSONArray(sp.getString(localProfileNumbered + "isf", defaultArray))
|
||||
} catch (e1: JSONException) {
|
||||
try {
|
||||
p.isf = JSONArray(defaultArray)
|
||||
} catch (ignored: JSONException) {
|
||||
}
|
||||
aapsLogger.error("Exception", e1)
|
||||
}
|
||||
|
||||
try {
|
||||
p.basal = JSONArray(sp.getString(localProfileNumbered + "basal", defaultArray))
|
||||
} catch (e1: JSONException) {
|
||||
try {
|
||||
p.basal = JSONArray(defaultArray)
|
||||
} catch (ignored: JSONException) {
|
||||
}
|
||||
aapsLogger.error("Exception", e1)
|
||||
}
|
||||
|
||||
try {
|
||||
p.targetLow = JSONArray(sp.getString(localProfileNumbered + "targetlow", defaultArray))
|
||||
} catch (e1: JSONException) {
|
||||
try {
|
||||
p.targetLow = JSONArray(defaultArray)
|
||||
} catch (ignored: JSONException) {
|
||||
}
|
||||
aapsLogger.error("Exception", e1)
|
||||
}
|
||||
|
||||
try {
|
||||
p.targetHigh = JSONArray(sp.getString(localProfileNumbered + "targethigh", defaultArray))
|
||||
} catch (e1: JSONException) {
|
||||
try {
|
||||
p.targetHigh = JSONArray(defaultArray)
|
||||
} catch (ignored: JSONException) {
|
||||
}
|
||||
aapsLogger.error("Exception", e1)
|
||||
profiles.add(p)
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Exception", e)
|
||||
}
|
||||
|
||||
profiles.add(p)
|
||||
}
|
||||
// create at least one profile if doesn't exist
|
||||
if (profiles.size < 1) profiles.add(defaultProfile())
|
||||
isEdited = false
|
||||
numOfProfiles = profiles.size
|
||||
createAndStoreConvertedProfile()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun loadFromStore(store: ProfileStore) {
|
||||
try {
|
||||
val newProfiles: ArrayList<SingleProfile> = ArrayList()
|
||||
for (p in store.getProfileList()) {
|
||||
store.getSpecificProfile(p.toString())?.let {
|
||||
val sp = copyFrom(it, p.toString())
|
||||
sp.name = p.toString()
|
||||
newProfiles.add(sp)
|
||||
}
|
||||
}
|
||||
if (newProfiles.size > 0) {
|
||||
profiles = newProfiles
|
||||
numOfProfiles = profiles.size
|
||||
currentProfileIndex = 0
|
||||
isEdited = false
|
||||
createAndStoreConvertedProfile()
|
||||
aapsLogger.debug(LTag.PROFILE, "Accepted ${profiles.size} profiles")
|
||||
rxBus.send(EventLocalProfileChanged())
|
||||
} else
|
||||
aapsLogger.debug(LTag.PROFILE, "ProfileStore not accepted")
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error("Error loading ProfileStore", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun defaultProfile(): SingleProfile =
|
||||
SingleProfile().also { p ->
|
||||
p.name = Constants.LOCAL_PROFILE
|
||||
p.mgdl = profileFunction.getUnits() == GlucoseUnit.MGDL
|
||||
p.dia = Constants.defaultDIA
|
||||
try {
|
||||
p.ic = JSONArray(defaultArray)
|
||||
p.isf = JSONArray(defaultArray)
|
||||
p.basal = JSONArray(defaultArray)
|
||||
p.targetLow = JSONArray(defaultArray)
|
||||
p.targetHigh = JSONArray(defaultArray)
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Exception", e)
|
||||
}
|
||||
}
|
||||
|
||||
fun copyFrom(pureProfile: PureProfile, newName: String): SingleProfile {
|
||||
var verifiedName = newName
|
||||
if (rawProfile?.getSpecificProfile(newName) != null) {
|
||||
|
@ -380,4 +387,36 @@ class LocalProfilePlugin @Inject constructor(
|
|||
get() = rawProfile?.getDefaultProfile()?.let {
|
||||
DecimalFormatter.to2Decimal(ProfileSealed.Pure(it).percentageBasalSum()) + "U "
|
||||
} ?: "INVALID"
|
||||
|
||||
// cannot be inner class because of needed injection
|
||||
class NSProfileWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : Worker(context, params) {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorker: DataWorker
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var localProfilePlugin: LocalProfilePlugin
|
||||
|
||||
init {
|
||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||
}
|
||||
|
||||
override fun doWork(): Result {
|
||||
val profileJson = dataWorker.pickupJSONObject(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
if (sp.getBoolean(R.string.key_ns_receive_profile_store, false) || config.NSCLIENT) {
|
||||
localProfilePlugin.loadFromStore(ProfileStore(injector, profileJson, dateUtil))
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: $profileJson")
|
||||
return Result.success(workDataOf("Data" to profileJson.toString()))
|
||||
}
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,170 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.profile.ns
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.ProfileSealed
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.databinding.NsprofileFragmentBinding
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.profile.ns.events.EventNSProfileUpdateGUI
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import javax.inject.Inject
|
||||
|
||||
class NSProfileFragment : DaggerFragment() {
|
||||
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var nsProfilePlugin: NSProfilePlugin
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var config: Config
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
|
||||
private var _binding: NsprofileFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
_binding = NsprofileFragmentBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.profileviewer.closeLayout.close.visibility = View.GONE // not needed for fragment
|
||||
|
||||
binding.profileswitch.setOnClickListener {
|
||||
val name = binding.spinner.selectedItem?.toString() ?: ""
|
||||
nsProfilePlugin.profile?.let { store ->
|
||||
store.getSpecificProfile(name)?.let {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.nsprofile),
|
||||
resourceHelper.gs(R.string.activate_profile) + ": " + name + " ?", Runnable {
|
||||
uel.log(Action.PROFILE_SWITCH, Sources.NSProfile,
|
||||
ValueWithUnit.SimpleString(name),
|
||||
ValueWithUnit.Percent(100))
|
||||
profileFunction.createProfileSwitch(store, name, 0, 100, 0, dateUtil.now())
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
if (_binding == null) return
|
||||
binding.profileviewer.invalidprofile.visibility = View.VISIBLE
|
||||
binding.profileviewer.noprofile.visibility = View.VISIBLE
|
||||
binding.profileviewer.units.text = ""
|
||||
binding.profileviewer.dia.text = ""
|
||||
binding.profileviewer.activeprofile.text = ""
|
||||
binding.profileviewer.ic.text = ""
|
||||
binding.profileviewer.isf.text = ""
|
||||
binding.profileviewer.basal.text = ""
|
||||
binding.profileviewer.basaltotal.text = ""
|
||||
binding.profileviewer.target.text = ""
|
||||
binding.profileswitch.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
if (_binding == null) return
|
||||
val name = binding.spinner.getItemAtPosition(position).toString()
|
||||
|
||||
binding.profileswitch.visibility = View.GONE
|
||||
|
||||
nsProfilePlugin.profile?.let { store ->
|
||||
store.getSpecificProfile(name)?.let { profile ->
|
||||
if (_binding == null) return
|
||||
val pss = ProfileSealed.Pure(profile)
|
||||
binding.profileviewer.units.text = pss.units.asText
|
||||
binding.profileviewer.dia.text = resourceHelper.gs(R.string.format_hours, pss.dia)
|
||||
binding.profileviewer.activeprofile.text = name
|
||||
binding.profileviewer.ic.text = pss.getIcList(resourceHelper, dateUtil)
|
||||
binding.profileviewer.isf.text = pss.getIsfList(resourceHelper, dateUtil)
|
||||
binding.profileviewer.basal.text = pss.getBasalList(resourceHelper, dateUtil)
|
||||
binding.profileviewer.basaltotal.text = String.format(resourceHelper.gs(R.string.profile_total), DecimalFormatter.to2Decimal(pss.baseBasalSum()))
|
||||
binding.profileviewer.target.text = pss.getTargetList(resourceHelper, dateUtil)
|
||||
binding.profileviewer.basalGraph.show(pss)
|
||||
if (pss.isValid("NSProfileFragment", activePlugin.activePump, config, resourceHelper, rxBus)) {
|
||||
binding.profileviewer.invalidprofile.visibility = View.GONE
|
||||
binding.profileswitch.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.profileviewer.invalidprofile.visibility = View.VISIBLE
|
||||
binding.profileswitch.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSProfileUpdateGUI::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ updateGUI() }, fabricPrivacy::logException)
|
||||
updateGUI()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun updateGUI() {
|
||||
if (_binding == null) return
|
||||
binding.profileviewer.noprofile.visibility = View.VISIBLE
|
||||
|
||||
nsProfilePlugin.profile?.let { profileStore ->
|
||||
context?.let { context ->
|
||||
val profileList = profileStore.getProfileList()
|
||||
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
|
||||
binding.spinner.adapter = adapter
|
||||
// set selected to actual profile
|
||||
for (p in profileList.indices) {
|
||||
if (profileList[p] == profileFunction.getProfileName())
|
||||
binding.spinner.setSelection(p)
|
||||
}
|
||||
binding.profileviewer.noprofile.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.profile.ns
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.events.EventProfileStoreChanged
|
||||
import info.nightscout.androidaps.interfaces.PluginBase
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.interfaces.ProfileSource
|
||||
import info.nightscout.androidaps.interfaces.ProfileStore
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
||||
import info.nightscout.androidaps.plugins.profile.ns.events.EventNSProfileUpdateGUI
|
||||
import info.nightscout.androidaps.receivers.DataWorker
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class NSProfilePlugin @Inject constructor(
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
private val rxBus: RxBusWrapper,
|
||||
resourceHelper: ResourceHelper,
|
||||
private val sp: SP,
|
||||
private val dateUtil: DateUtil,
|
||||
config: Config
|
||||
) : PluginBase(PluginDescription()
|
||||
.mainType(PluginType.PROFILE)
|
||||
.fragmentClass(NSProfileFragment::class.java.name)
|
||||
.pluginIcon(R.drawable.ic_nightscout_profile)
|
||||
.pluginName(R.string.nsprofile)
|
||||
.shortName(R.string.profileviewer_shortname)
|
||||
.alwaysEnabled(config.NSCLIENT)
|
||||
.alwaysVisible(config.NSCLIENT)
|
||||
.showInList(!config.NSCLIENT)
|
||||
.description(R.string.description_profile_nightscout),
|
||||
aapsLogger, resourceHelper, injector
|
||||
), ProfileSource {
|
||||
|
||||
override var profile: ProfileStore? = null
|
||||
|
||||
override val profileName: String?
|
||||
get() = profile?.getDefaultProfileName()
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
loadNSProfile()
|
||||
}
|
||||
|
||||
private fun storeNSProfile() {
|
||||
sp.putString("profile", profile!!.data.toString())
|
||||
aapsLogger.debug(LTag.PROFILE, "Storing profile")
|
||||
}
|
||||
|
||||
private fun loadNSProfile() {
|
||||
aapsLogger.debug(LTag.PROFILE, "Loading stored profile")
|
||||
val profileString = sp.getStringOrNull("profile", null)
|
||||
if (profileString != null) {
|
||||
aapsLogger.debug(LTag.PROFILE, "Loaded profile: $profileString")
|
||||
profile = ProfileStore(injector, JSONObject(profileString), dateUtil)
|
||||
} else {
|
||||
aapsLogger.debug(LTag.PROFILE, "Stored profile not found")
|
||||
// force restart of nsclient to fetch profile
|
||||
rxBus.send(EventNSClientRestart())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// cannot be inner class because of needed injection
|
||||
class NSProfileWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : Worker(context, params) {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var nsProfilePlugin: NSProfilePlugin
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorker: DataWorker
|
||||
|
||||
init {
|
||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||
}
|
||||
|
||||
override fun doWork(): Result {
|
||||
val profileString = dataWorker.pickupJSONObject(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
nsProfilePlugin.profile = ProfileStore(injector, profileString, dateUtil)
|
||||
nsProfilePlugin.storeNSProfile()
|
||||
if (nsProfilePlugin.isEnabled()) {
|
||||
rxBus.send(EventProfileStoreChanged())
|
||||
rxBus.send(EventNSProfileUpdateGUI())
|
||||
}
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: ${nsProfilePlugin.profile}")
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.profile.ns.events
|
||||
|
||||
import info.nightscout.androidaps.events.EventUpdateGui
|
||||
|
||||
class EventNSProfileUpdateGUI : EventUpdateGui()
|
|
@ -61,7 +61,7 @@ class MDIPlugin @Inject constructor(
|
|||
override fun waitForDisconnectionInSeconds(): Int = 0
|
||||
override fun stopConnecting() {}
|
||||
override fun getPumpStatus(reason: String) {}
|
||||
override fun setNewBasalProfile(profile: Profile): PumpEnactResult = PumpEnactResult(injector).success(true)
|
||||
override fun setNewBasalProfile(profile: Profile): PumpEnactResult = PumpEnactResult(injector).success(true).enacted(true)
|
||||
override fun isThisProfileSet(profile: Profile): Boolean = false
|
||||
override fun lastDataTime(): Long = System.currentTimeMillis()
|
||||
override val baseBasalRate: Double = 0.0
|
||||
|
|
|
@ -4,12 +4,12 @@ import android.os.SystemClock
|
|||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.SwitchPreference
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||
import info.nightscout.androidaps.extensions.convertedToAbsolute
|
||||
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
|
@ -25,8 +25,6 @@ import info.nightscout.androidaps.utils.FabricPrivacy
|
|||
import info.nightscout.androidaps.utils.InstanceId.instanceId
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.TimeChangeType
|
||||
import info.nightscout.androidaps.extensions.convertedToAbsolute
|
||||
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
|
@ -139,7 +137,6 @@ open class VirtualPumpPlugin @Inject constructor(
|
|||
override fun isHandshakeInProgress(): Boolean = false
|
||||
|
||||
override fun connect(reason: String) {
|
||||
//if (!Config.NSCLIENT) NSUpload.uploadDeviceStatus()
|
||||
lastDataTime = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
|
@ -152,12 +149,9 @@ open class VirtualPumpPlugin @Inject constructor(
|
|||
|
||||
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
|
||||
lastDataTime = System.currentTimeMillis()
|
||||
rxBus.send(EventNewNotification(Notification(Notification.PROFILE_SET_OK, resourceHelper.gs(R.string.profile_set_ok), Notification.INFO, 60)))
|
||||
// Do nothing here. we are using database profile
|
||||
val result = PumpEnactResult(injector)
|
||||
result.success = true
|
||||
val notification = Notification(Notification.PROFILE_SET_OK, resourceHelper.gs(R.string.profile_set_ok), Notification.INFO, 60)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
return result
|
||||
return PumpEnactResult(injector).success(true).enacted(true)
|
||||
}
|
||||
|
||||
override fun isThisProfileSet(profile: Profile): Boolean {
|
||||
|
@ -400,7 +394,7 @@ open class VirtualPumpPlugin @Inject constructor(
|
|||
aapsLogger.debug(LTag.PUMP, "Pump in configuration: $pumpType, PumpType object: $pumpTypeNew")
|
||||
if (this.pumpType == pumpTypeNew) return
|
||||
aapsLogger.debug(LTag.PUMP, "New pump configuration found ($pumpTypeNew), changing from previous (${this.pumpType})")
|
||||
pumpDescription.setPumpDescription(pumpTypeNew)
|
||||
pumpDescription.fillFor(pumpTypeNew)
|
||||
this.pumpType = pumpTypeNew
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@ import androidx.work.Worker
|
|||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
|
||||
import info.nightscout.androidaps.interfaces.BgSource
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.interfaces.PluginBase
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
|
@ -115,7 +115,7 @@ class NSClientSourcePlugin @Inject constructor(
|
|||
override fun doWork(): Result {
|
||||
var ret = Result.success()
|
||||
|
||||
if (!nsClientSourcePlugin.isEnabled() && !sp.getBoolean(R.string.key_ns_autobackfill, true) && !dexcomPlugin.isEnabled()) return Result.success()
|
||||
if (!nsClientSourcePlugin.isEnabled() && !sp.getBoolean(R.string.key_ns_receive_cgm, true) && !dexcomPlugin.isEnabled()) return Result.success()
|
||||
|
||||
val sgvs = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
|
|
|
@ -105,25 +105,10 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
|
|||
return wrapped.queryForAll();
|
||||
}
|
||||
|
||||
public void delete(Treatment data) throws SQLException {
|
||||
wrapped.delete(data);
|
||||
openHumansUploader.enqueueTreatment(data, true);
|
||||
}
|
||||
|
||||
public void create(Treatment data) throws SQLException {
|
||||
wrapped.create(data);
|
||||
openHumansUploader.enqueueTreatment(data);
|
||||
}
|
||||
|
||||
public Treatment queryForId(long id) throws SQLException {
|
||||
return wrapped.queryForId(id);
|
||||
}
|
||||
|
||||
public void update(Treatment data) throws SQLException {
|
||||
wrapped.update(data);
|
||||
openHumansUploader.enqueueTreatment(data);
|
||||
}
|
||||
|
||||
public QueryBuilder<Treatment, Long> queryBuilder() {
|
||||
return wrapped.queryBuilder();
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import info.nightscout.androidaps.interfaces.TreatmentServiceInterface;
|
|||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
|
@ -37,12 +36,10 @@ import io.reactivex.disposables.CompositeDisposable;
|
|||
@Singleton
|
||||
public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface {
|
||||
|
||||
private final AapsSchedulers aapsSchedulers;
|
||||
private final SP sp;
|
||||
private final RxBusWrapper rxBus;
|
||||
private final ProfileFunction profileFunction;
|
||||
private final ActivePlugin activePlugin;
|
||||
private final NSUpload nsUpload;
|
||||
private final FabricPrivacy fabricPrivacy;
|
||||
private final DateUtil dateUtil;
|
||||
private final DatabaseHelperInterface databaseHelper;
|
||||
|
@ -63,7 +60,6 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
SP sp,
|
||||
ProfileFunction profileFunction,
|
||||
ActivePlugin activePlugin,
|
||||
NSUpload nsUpload,
|
||||
FabricPrivacy fabricPrivacy,
|
||||
DateUtil dateUtil,
|
||||
DatabaseHelperInterface databaseHelper,
|
||||
|
@ -81,13 +77,11 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
aapsLogger, resourceHelper, injector
|
||||
);
|
||||
this.rxBus = rxBus;
|
||||
this.aapsSchedulers = aapsSchedulers;
|
||||
this.sp = sp;
|
||||
this.profileFunction = profileFunction;
|
||||
this.activePlugin = activePlugin;
|
||||
this.fabricPrivacy = fabricPrivacy;
|
||||
this.dateUtil = dateUtil;
|
||||
this.nsUpload = nsUpload;
|
||||
this.databaseHelper = databaseHelper;
|
||||
this.repository = repository;
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
})
|
||||
}
|
||||
}
|
||||
val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode()
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_insulin, false) || !sp.getBoolean(R.string.key_ns_receive_carbs, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
|
|
|
@ -102,7 +102,7 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode()
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
|
|
|
@ -21,12 +21,10 @@ import info.nightscout.androidaps.dialogs.ProfileViewerDialog
|
|||
import info.nightscout.androidaps.events.EventProfileSwitchChanged
|
||||
import info.nightscout.androidaps.extensions.getCustomizedName
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.interfaces.UploadQueueInterface
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
|
@ -55,8 +53,6 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
@Inject lateinit var localProfilePlugin: LocalProfilePlugin
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var nsUpload: NSUpload
|
||||
@Inject lateinit var uploadQueue: UploadQueueInterface
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
|
@ -103,7 +99,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode()) binding.refreshFromNightscout.visibility = View.GONE
|
||||
if (!sp.getBoolean(R.string.key_ns_receive_profile_switch, false) || !buildHelper.isEngineeringMode()) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import info.nightscout.androidaps.databinding.TreatmentsTemptargetFragmentBindin
|
|||
import info.nightscout.androidaps.databinding.TreatmentsTemptargetItemBinding
|
||||
import info.nightscout.androidaps.events.EventTempTargetChange
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.interfaces.UploadQueueInterface
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
|
@ -58,7 +57,6 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var uploadQueue: UploadQueueInterface
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var translator: Translator
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
|
@ -99,7 +97,7 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
})
|
||||
}
|
||||
}
|
||||
val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode()
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_temp_target, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.INVISIBLE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
|
@ -151,7 +149,7 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
_binding = null
|
||||
}
|
||||
|
||||
private inner class RecyclerViewAdapter internal constructor(private var tempTargetList: List<TemporaryTarget>) : RecyclerView.Adapter<TempTargetsViewHolder>() {
|
||||
private inner class RecyclerViewAdapter(private var tempTargetList: List<TemporaryTarget>) : RecyclerView.Adapter<TempTargetsViewHolder>() {
|
||||
|
||||
private val dbRecord = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
|
||||
private val currentlyActiveTarget = if (dbRecord is ValueWrapper.Existing) dbRecord.value else null
|
||||
|
|
|
@ -6,6 +6,7 @@ import info.nightscout.androidaps.data.PumpEnactResult
|
|||
import info.nightscout.androidaps.database.ValueWrapper
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
|
@ -25,9 +26,10 @@ class CommandSetProfile constructor(
|
|||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var commandQueue: CommandQueueProvider
|
||||
@Inject lateinit var config: Config
|
||||
|
||||
override fun execute() {
|
||||
if (commandQueue.isThisProfileSet(profile)) {
|
||||
if (commandQueue.isThisProfileSet(profile) && repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing) {
|
||||
aapsLogger.debug(LTag.PUMPQUEUE, "Correct profile already set. profile: $profile")
|
||||
callback?.result(PumpEnactResult(injector).success(true).enacted(false))?.run()
|
||||
return
|
||||
|
@ -37,7 +39,7 @@ class CommandSetProfile constructor(
|
|||
callback?.result(r)?.run()
|
||||
// Send SMS notification if ProfileSwitch is coming from NS
|
||||
val profileSwitch = repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet()
|
||||
if (profileSwitch is ValueWrapper.Existing && r.enacted && hasNsId) {
|
||||
if (profileSwitch is ValueWrapper.Existing && r.enacted && hasNsId && !config.NSCLIENT) {
|
||||
if (smsCommunicatorPlugin.isEnabled(PluginType.GENERAL))
|
||||
smsCommunicatorPlugin.sendNotificationToAllNumbers(resourceHelper.gs(R.string.profile_set_ok))
|
||||
}
|
||||
|
|
|
@ -129,7 +129,8 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
|
|||
if (lastReadStatus != 0L && lastReadStatus > System.currentTimeMillis() - T.mins(5).msecs()) {
|
||||
localAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated, loopPlugin.isDisconnected)
|
||||
}
|
||||
if (!pump.isThisProfileSet(profile) && !commandQueue.isRunning(Command.CommandType.BASAL_PROFILE)) {
|
||||
if (!pump.isThisProfileSet(profile) && !commandQueue.isRunning(Command.CommandType.BASAL_PROFILE)
|
||||
|| profileFunction.getProfile() == null) {
|
||||
rxBus.send(EventProfileSwitchChanged())
|
||||
} else if (isStatusOutdated && !pump.isBusy()) {
|
||||
lastReadStatus = System.currentTimeMillis()
|
||||
|
|
|
@ -19,11 +19,8 @@ import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesFragm
|
|||
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.OmnipodDashPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugin
|
||||
|
@ -53,7 +50,6 @@ class SWDefinition @Inject constructor(
|
|||
private val configBuilder: ConfigBuilder,
|
||||
private val loopPlugin: LoopPlugin,
|
||||
private val nsClientPlugin: NSClientPlugin,
|
||||
private val nsProfilePlugin: NSProfilePlugin,
|
||||
private val importExportPrefs: ImportExportPrefs,
|
||||
private val androidPermission: AndroidPermission,
|
||||
private val cryptoUtil: CryptoUtil,
|
||||
|
@ -189,8 +185,8 @@ class SWDefinition @Inject constructor(
|
|||
.label(R.string.status)
|
||||
.initialStatus(nsClientPlugin.status)
|
||||
)
|
||||
.validator { nsClientPlugin.nsClientService != null && NSClientService.isConnected && NSClientService.hasWriteAuth }
|
||||
.visibility { !(nsClientPlugin.nsClientService != null && NSClientService.isConnected && NSClientService.hasWriteAuth) }
|
||||
.validator { nsClientPlugin.nsClientService?.isConnected == true && nsClientPlugin.nsClientService?.hasWriteAuth == true }
|
||||
.visibility { !(nsClientPlugin.nsClientService?.isConnected == true && nsClientPlugin.nsClientService?.hasWriteAuth == true) }
|
||||
private val screenPatientName = SWScreen(injector, R.string.patient_name)
|
||||
.skippable(true)
|
||||
.add(SWInfoText(injector)
|
||||
|
@ -254,27 +250,14 @@ class SWDefinition @Inject constructor(
|
|||
.option(PluginType.BGSOURCE, R.string.configbuilder_bgsource_description)
|
||||
.label(R.string.configbuilder_bgsource))
|
||||
.add(SWBreak(injector))
|
||||
private val screenProfile = SWScreen(injector, R.string.configbuilder_profile)
|
||||
.skippable(false)
|
||||
.add(SWInfoText(injector)
|
||||
.label(R.string.setupwizard_profile_description))
|
||||
.add(SWBreak(injector))
|
||||
.add(SWPlugin(injector, this)
|
||||
.option(PluginType.PROFILE, R.string.configbuilder_profile_description)
|
||||
.label(R.string.configbuilder_profile))
|
||||
private val screenNsProfile = SWScreen(injector, R.string.nsprofile)
|
||||
.skippable(false)
|
||||
.add(SWInfoText(injector)
|
||||
.label(R.string.adjustprofileinns))
|
||||
.add(SWFragment(injector, this)
|
||||
.add(NSProfileFragment()))
|
||||
.validator { nsProfilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, resourceHelper, rxBus) } ?: false }
|
||||
.visibility { nsProfilePlugin.isEnabled() }
|
||||
private val screenLocalProfile = SWScreen(injector, R.string.localprofile)
|
||||
.skippable(false)
|
||||
.add(SWFragment(injector, this)
|
||||
.add(LocalProfileFragment()))
|
||||
.validator { localProfilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, resourceHelper, rxBus) } ?: false }
|
||||
.validator {
|
||||
localProfilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, resourceHelper, rxBus) }
|
||||
?: false
|
||||
}
|
||||
.visibility { localProfilePlugin.isEnabled() }
|
||||
private val screenProfileSwitch = SWScreen(injector, R.string.careportal_profileswitch)
|
||||
.skippable(false)
|
||||
|
@ -399,8 +382,6 @@ class SWDefinition @Inject constructor(
|
|||
.add(screenAge)
|
||||
.add(screenInsulin)
|
||||
.add(screenBgSource)
|
||||
.add(screenProfile)
|
||||
.add(screenNsProfile)
|
||||
.add(screenLocalProfile)
|
||||
.add(screenProfileSwitch)
|
||||
.add(screenPump)
|
||||
|
@ -428,8 +409,6 @@ class SWDefinition @Inject constructor(
|
|||
.add(screenAge)
|
||||
.add(screenInsulin)
|
||||
.add(screenBgSource)
|
||||
.add(screenProfile)
|
||||
.add(screenNsProfile)
|
||||
.add(screenLocalProfile)
|
||||
.add(screenProfileSwitch)
|
||||
.add(screenPump)
|
||||
|
|
|
@ -92,8 +92,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="5"
|
||||
android:paddingBottom="10dp">
|
||||
android:paddingBottom="10dp"
|
||||
android:weightSum="5">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dia_tab"
|
||||
|
@ -228,10 +228,24 @@
|
|||
|
||||
<LinearLayout
|
||||
android:id="@+id/basal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="vertical" />
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/basal_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<info.nightscout.androidaps.plugins.treatments.fragments.ProfileGraph
|
||||
android:id="@+id/basal_graph"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dip"
|
||||
android:layout_margin="20dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/target"
|
||||
|
@ -248,15 +262,15 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_local_activate"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="@string/activate_profile"
|
||||
android:drawableStart="@drawable/ic_local_activate" />
|
||||
android:text="@string/activate_profile" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -75,15 +75,6 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:textStyle="normal|bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/queue"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="5dp"
|
||||
android:text="@string/queue"
|
||||
android:textAlignment="viewEnd"
|
||||
tools:ignore="RtlHardcoded" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
@ -125,26 +116,6 @@
|
|||
android:textColor="@android:color/holo_orange_light"
|
||||
android:textStyle="normal|bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/clear_queue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/clear_queue"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@android:color/holo_orange_light"
|
||||
android:textStyle="normal|bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/show_queue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/show_queue"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@android:color/holo_orange_light"
|
||||
android:textStyle="normal|bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/full_sync"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="5dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/profileswitch"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/activate_profile"
|
||||
android:textColor="@color/colorProfileSwitchButton" />
|
||||
|
||||
<include
|
||||
android:id="@+id/profileviewer"
|
||||
layout="@layout/profileviewer_fragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
|
||||
</LinearLayout>
|
|
@ -1,453 +0,0 @@
|
|||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".plugins.profile.ns.NSProfileFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/invalidprofile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/invalidprofile"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textColor="@android:color/holo_red_light"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/noprofile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/noprofileset"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textColor="@android:color/holo_red_light"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="2"
|
||||
android:gravity="end"
|
||||
android:text="@string/careportal_newnstreatment_profile_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activeprofile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter"
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/datelayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="2"
|
||||
android:gravity="end"
|
||||
android:text="@string/date"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/date"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="2"
|
||||
android:gravity="end"
|
||||
android:text="@string/units_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/units"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="2"
|
||||
android:gravity="end"
|
||||
android:text="@string/dia_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dia"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="2"
|
||||
android:gravity="end"
|
||||
android:text="@string/ic_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ic"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="2"
|
||||
android:gravity="end"
|
||||
android:text="@string/isf_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/isf"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="2"
|
||||
android:gravity="end"
|
||||
android:text="@string/basal_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/basal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="2"
|
||||
android:gravity="end"
|
||||
android:text=""
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:text=""
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/basaltotal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="17dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<info.nightscout.androidaps.plugins.treatments.fragments.ProfileGraph
|
||||
android:id="@+id/basal_graph"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dip"
|
||||
android:layout_margin="20dp" />
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="2"
|
||||
android:gravity="end"
|
||||
android:text="@string/target_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/target"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/reload"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/reloadprofile"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
android:id="@+id/close_layout"
|
||||
layout="@layout/close" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
|
@ -47,6 +47,8 @@
|
|||
<string name="key_ns_temporary_basal_last_synced_id" translatable="false">ns_temporary_basal_last_synced_id</string>
|
||||
<string name="key_ns_extended_bolus_last_synced_id" translatable="false">ns_extended_bolus_last_synced_id</string>
|
||||
<string name="key_ns_profile_switch_last_synced_id" translatable="false">profile_switch_last_synced_id</string>
|
||||
<string name="key_ns_profile_store_last_synced_timestamp" translatable="false">ns_profile_store_last_synced_timestamp</string>
|
||||
<string name="key_local_profile_last_change" translatable="false">local_profile_last_change</string>
|
||||
|
||||
<string name="treatmentssafety_title">Treatments safety</string>
|
||||
<string name="treatmentssafety_maxbolus_title">Max allowed bolus [U]</string>
|
||||
|
@ -76,7 +78,6 @@
|
|||
<string name="description_overview">Displays the current state of your loop and buttons for most common actions</string>
|
||||
<string name="description_persistent_notification">Shows an ongoing notification with a short overview of what your loop is doing</string>
|
||||
<string name="description_profile_local">Define a profile which is available offline.</string>
|
||||
<string name="description_profile_nightscout">Provides the profile you have defined in Nightscout</string>
|
||||
<string name="description_pump_mdi">Pump integration for people who do multiple daily injections for their diabetes therapy</string>
|
||||
<string name="description_pump_virtual">Pump integration for pumps which don\'t have any driver yet (Open Loop)</string>
|
||||
<string name="description_sensitivity_aaps">Sensitivity is calculated the same way like Oref0, but you can specify timeframe to the past. Minimal carb absorption is calculated from max carb absorption time from preferences.</string>
|
||||
|
@ -126,7 +127,6 @@
|
|||
|
||||
<string name="configbuilder">Config Builder</string>
|
||||
<string name="overview">Overview</string>
|
||||
<string name="nsprofile">NS Profile</string>
|
||||
<string name="treatments">Treatments</string>
|
||||
<string name="virtualpump">Virtual Pump</string>
|
||||
<string name="careportal">Careportal</string>
|
||||
|
@ -338,7 +338,6 @@
|
|||
<string name="localprofile_shortname">LP</string>
|
||||
<string name="overview_shortname">HOME</string>
|
||||
<string name="virtualpump_shortname">VPUMP</string>
|
||||
<string name="profileviewer_shortname">NSPROFILE</string>
|
||||
<string name="treatments_shortname">TREAT</string>
|
||||
<string name="objectives_shortname">OBJ</string>
|
||||
<string name="wear_shortname">WEAR</string>
|
||||
|
@ -497,10 +496,6 @@
|
|||
<string name="xdripstatus_shortname">xds</string>
|
||||
<string name="wear_showbgi_title">Show BGI</string>
|
||||
<string name="wear_showbgi_summary">Add BGI to status line</string>
|
||||
<string name="ns_noupload">No upload to NS</string>
|
||||
<string name="ns_noupload_summary">All data sent to NS are dropped. AAPS is connected to NS but no change in NS is done</string>
|
||||
<string name="key_ns_upload_only" translatable="false">ns_upload_only2</string>
|
||||
<string name="key_ns_noupload" translatable="false">ns_noupload</string>
|
||||
<string name="overview_extendedbolus_cancel_button">Cancel Extended Bolus</string>
|
||||
<string name="doprofileswitch">Do Profile Switch</string>
|
||||
<string name="careportal_sensor_label">Sensor</string>
|
||||
|
@ -697,8 +692,6 @@
|
|||
<string name="category">Category</string>
|
||||
<string name="subcategory">Subcategory</string>
|
||||
<string name="bolusrecordedonly">Bolus will be recorded only (not delivered by pump)</string>
|
||||
<string name="ns_autobackfill_summary">Autobackfill missig BGs from NS</string>
|
||||
<string name="key_ns_autobackfill" translatable="false">ns_autobackfill</string>
|
||||
<string name="loop_smbsetbypump_label">SMB set by pump</string>
|
||||
<string name="overview_show_activity">Activity</string>
|
||||
<string name="overview_show_bgi">Blood Glucose Impact</string>
|
||||
|
@ -781,7 +774,6 @@
|
|||
<string name="virtualpump_type">Virtual Pump Type</string>
|
||||
<string name="virtualpump_definition">Pump Definition</string>
|
||||
<string name="virtualpump_pump_def">Bolus: Step=%1$s\nExtended Bolus: [Step=%2$s, Duration=%3$smin-%4$sh]\nBasal: Step=%5$s\nTBR: %6$s (by %7$s), Duration=%8$smin-%9$sh\n%10$s</string>
|
||||
<string name="ns_autobackfill_title">Autobackfill BG</string>
|
||||
<string name="wear_wizard_settings">Wizard Settings</string>
|
||||
<string name="key_wearwizard_bg" translatable="false">wearwizard_bg</string>
|
||||
<string name="key_wearwizard_tt" translatable="false">wearwizard_tt</string>
|
||||
|
@ -795,7 +787,6 @@
|
|||
<string name="enable_nsclient">Enable NSClient</string>
|
||||
<string name="welcometosetupwizard">Welcome to setup wizard. It will guide you through the setup process\n</string>
|
||||
<string name="readstatus">Read status</string>
|
||||
<string name="adjustprofileinns">Changes must be done in NS</string>
|
||||
<string name="exitwizard">Skip setup wizard</string>
|
||||
<string name="setupwizard_loop_description">Press the button below to enable AndroidAPS to suggest/make basal changes</string>
|
||||
<string name="key_setupwizard_processed" translatable="false">startupwizard_processed</string>
|
||||
|
@ -803,7 +794,6 @@
|
|||
<string name="setupwizard_sensitivity_url">https://github.com/MilosKozak/AndroidAPS/wiki/Sensitivity-detection-and-COB</string>
|
||||
<string name="nsclientinfotext">NSClient handles connection to Nightscout. You can skip this part now but you will not be able to pass objectives until you set it up.</string>
|
||||
<string name="diawarning">Please remember: new insulin profiles require DIA at least 5h. DIA 5–6h on new profile is equal to DIA 3h on old insulin profiles.</string>
|
||||
<string name="setupwizard_profile_description">Please select source of profile. If patient is a child you should use NS profile. If there is nobody following you on Nightscout you will probably prefer Local profile. Please remember that you are only selecting the profile source. To use it you must activate it by executing \"Profile switch\"</string>
|
||||
<string name="setupwizard_aps_description">Select one from availables algorithms. They are sorted from oldest to newest. Newer algorithm is usually more powerful and more aggressive. Thus if you are new looper you may probably start with AMA and not with latest one. Do not forget to read the OpenAPS documentation and configure it before use.</string>
|
||||
<string name="setupwizard_pump_waiting_for_riley_link_connection">Please configure your RileyLink below. After selecting a RileyLink, it will be possible to continue setup once the RileyLink status is \"Connected\". This might take a minute.\n</string>
|
||||
<string name="setupwizard_pump_pump_not_initialized"><b>Note:</b> You can continue setup once the pump has been set up.\n</string>
|
||||
|
@ -952,7 +942,6 @@
|
|||
<string name="objectives_button_unstart">Clear started</string>
|
||||
<string name="doyouwantresetstart">Do you want reset objective start? You may lose your progress.</string>
|
||||
<string name="setupwizard_units_prompt">Select units you want to display values in</string>
|
||||
<string name="ns_ploadlocalprofile">Upload local profile changes to NS</string>
|
||||
<string name="key_wear_detailediob" translatable="false">wear_detailediob</string>
|
||||
<string name="key_wear_showbgi" translatable="false">wear_showbgi</string>
|
||||
<string name="dia_short">DIA</string>
|
||||
|
@ -1137,5 +1126,30 @@
|
|||
<string name="profile_carbs_ratio_value">Profile carbs ratio value</string>
|
||||
<string name="full_sync">Full sync</string>
|
||||
<string name="prime">Prime</string>
|
||||
<string name="ns_sync_options">Synchronization</string>
|
||||
<string name="key_ns_upload" translatable="false">ns_upload</string>
|
||||
<string name="ns_upload_summary">Profiles, boluses, carbs, temporary basals are uploaded to NS</string>
|
||||
<string name="ns_upload">Upload data to NS</string>
|
||||
<string name="key_ns_receive_profile_store" translatable="false">ns_receive_profile_store</string>
|
||||
<string name="ns_receive_profile_store">Receive profile store</string>
|
||||
<string name="ns_receive_profile_store_summary">Synchronized profiles from NS profile editor to Local profile</string>
|
||||
<string name="key_ns_receive_temp_target" translatable="false">ns_receive_temp_target</string>
|
||||
<string name="ns_receive_temp_target">Receive temporary targets</string>
|
||||
<string name="ns_receive_temp_target_summary">Accept temporary targets entered through NS or NSClient</string>
|
||||
<string name="key_ns_receive_profile_switch" translatable="false">ns_receive_profile_switch</string>
|
||||
<string name="ns_receive_profile_switch">Receive profile switches</string>
|
||||
<string name="ns_receive_profile_switch_summary">Accept profile switches entered through NS or NSClient</string>
|
||||
<string name="key_ns_receive_insulin" translatable="false">ns_receive_insulin</string>
|
||||
<string name="ns_receive_insulin">Receive insulin</string>
|
||||
<string name="ns_receive_insulin_summary">Accept insulin entered through NS or NSClient (it\'s not delivered, only calculated towards IOB)</string>
|
||||
<string name="key_ns_receive_carbs" translatable="false">ns_receive_carbs</string>
|
||||
<string name="ns_receive_carbs">Receive carbs</string>
|
||||
<string name="ns_receive_carbs_summary">Accept carbs entered through NS or NSClient</string>
|
||||
<string name="key_ns_receive_therapy_events" translatable="false">ns_receive_therapy_events</string>
|
||||
<string name="ns_receive_therapy_events">Receive therapy events</string>
|
||||
<string name="ns_receive_therapy_events_summary">Accept therapy events (cannula, insulin, battery change etc) entered through NS or NSClient</string>
|
||||
<string name="key_ns_receive_cgm" translatable="false">ns_receive_cgm</string>
|
||||
<string name="ns_receive_cgm">Receive/backfill CGM data</string>
|
||||
<string name="ns_receive_cgm_summary">Accept CGM data from NS</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -26,17 +26,59 @@
|
|||
validate:minLength="12"
|
||||
validate:testType="minLength"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_logappstartedevent"
|
||||
android:title="@string/ns_logappstartedevent"
|
||||
android:summary="@string/ns_logappstartedevent"
|
||||
/>
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="@string/ns_sync_options"
|
||||
android:title="@string/ns_sync_options">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_uploadlocalprofile"
|
||||
android:title="@string/ns_ploadlocalprofile" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_upload"
|
||||
android:summary="@string/ns_upload_summary"
|
||||
android:title="@string/ns_upload" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_cgm"
|
||||
android:summary="@string/ns_receive_cgm_summary"
|
||||
android:title="@string/ns_receive_cgm" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_profile_store"
|
||||
android:summary="@string/ns_receive_profile_store_summary"
|
||||
android:title="@string/ns_receive_profile_store" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_temp_target"
|
||||
android:summary="@string/ns_receive_temp_target_summary"
|
||||
android:title="@string/ns_receive_temp_target" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_profile_switch"
|
||||
android:summary="@string/ns_receive_profile_switch_summary"
|
||||
android:title="@string/ns_receive_profile_switch" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_insulin"
|
||||
android:summary="@string/ns_receive_insulin_summary"
|
||||
android:title="@string/ns_receive_insulin" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_carbs"
|
||||
android:summary="@string/ns_receive_carbs_summary"
|
||||
android:title="@string/ns_receive_carbs" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_therapy_events"
|
||||
android:summary="@string/ns_receive_therapy_events_summary"
|
||||
android:title="@string/ns_receive_therapy_events" />
|
||||
|
||||
</androidx.preference.PreferenceScreen>>
|
||||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="@string/ns_alarmoptions"
|
||||
|
@ -113,9 +155,10 @@
|
|||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_autobackfill"
|
||||
android:summary="@string/ns_autobackfill_summary"
|
||||
android:title="@string/ns_autobackfill_title" />
|
||||
android:key="@string/key_ns_logappstartedevent"
|
||||
android:title="@string/ns_logappstartedevent"
|
||||
android:summary="@string/ns_logappstartedevent"
|
||||
/>
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
|
@ -135,18 +178,6 @@
|
|||
android:summary="@string/ns_localbroadcasts"
|
||||
android:title="@string/ns_localbroadcasts_title" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_upload_only"
|
||||
android:summary="@string/ns_upload_only_summary"
|
||||
android:title="@string/ns_upload_only" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_noupload"
|
||||
android:summary="@string/ns_noupload_summary"
|
||||
android:title="@string/ns_noupload" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_sync_use_absolute"
|
||||
|
|
|
@ -18,7 +18,6 @@ import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugi
|
|||
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.Objective
|
||||
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage
|
||||
|
@ -64,8 +63,6 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
@Mock lateinit var glimpPlugin: GlimpPlugin
|
||||
@Mock lateinit var sensitivityOref1Plugin: SensitivityOref1Plugin
|
||||
@Mock lateinit var profiler: Profiler
|
||||
@Mock lateinit var nsUpload: NSUpload
|
||||
@Mock lateinit var uploadQueue: UploadQueueInterface
|
||||
@Mock lateinit var uel: UserEntryLogger
|
||||
@Mock lateinit var loggerUtils: LoggerUtils
|
||||
@Mock lateinit var databaseHelper: DatabaseHelperInterface
|
||||
|
@ -144,7 +141,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
comboPlugin = ComboPlugin(injector, aapsLogger, rxBus, resourceHelper, profileFunction, sp, commandQueue, context, databaseHelper, pumpSync, dateUtil)
|
||||
danaRPlugin = DanaRPlugin(injector, aapsLogger, aapsSchedulers, rxBus, context, resourceHelper, constraintChecker, activePlugin, sp, commandQueue, danaPump, dateUtil, fabricPrivacy, pumpSync)
|
||||
danaRSPlugin = DanaRSPlugin(injector, aapsLogger, aapsSchedulers, rxBus, context, resourceHelper, constraintChecker, profileFunction, sp, commandQueue, danaPump, pumpSync, detailedBolusInfoStorage, temporaryBasalStorage, fabricPrivacy, dateUtil)
|
||||
insightPlugin = LocalInsightPlugin(injector, aapsLogger, rxBus, resourceHelper, treatmentsInterface, sp, commandQueue, profileFunction, nsUpload, context, uploadQueue, ConfigImpl(), dateUtil, databaseHelper, pumpSync)
|
||||
insightPlugin = LocalInsightPlugin(injector, aapsLogger, rxBus, resourceHelper, treatmentsInterface, sp, commandQueue, profileFunction, context, ConfigImpl(), dateUtil, databaseHelper, pumpSync)
|
||||
openAPSSMBPlugin = OpenAPSSMBPlugin(injector, aapsLogger, rxBus, constraintChecker, resourceHelper, profileFunction, context, activePlugin, iobCobCalculator, hardLimits, profiler, sp, dateUtil, repository, glucoseStatusProvider)
|
||||
openAPSAMAPlugin = OpenAPSAMAPlugin(injector, aapsLogger, rxBus, constraintChecker, resourceHelper, profileFunction, context, activePlugin, iobCobCalculator, hardLimits, profiler, fabricPrivacy, dateUtil, repository, glucoseStatusProvider)
|
||||
safetyPlugin = SafetyPlugin(injector, aapsLogger, resourceHelper, sp, rxBus, constraintChecker, openAPSAMAPlugin, openAPSSMBPlugin, sensitivityOref1Plugin, activePlugin, hardLimits, BuildHelper(ConfigImpl(), loggerUtils), iobCobCalculator, ConfigImpl(), dateUtil)
|
||||
|
|
|
@ -6,8 +6,6 @@ import info.nightscout.androidaps.TestBaseWithProfile
|
|||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.db.TemporaryBasal
|
||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
||||
import info.nightscout.androidaps.interfaces.UploadQueueInterface
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
|
@ -24,8 +22,6 @@ class TreatmentsPluginTest : TestBaseWithProfile() {
|
|||
|
||||
@Mock lateinit var sp: SP
|
||||
@Mock lateinit var treatmentService: TreatmentService
|
||||
@Mock lateinit var nsUpload: NSUpload
|
||||
@Mock lateinit var uploadQueue: UploadQueueInterface
|
||||
@Mock lateinit var repository: AppRepository
|
||||
@Mock lateinit var databaseHelper: DatabaseHelperInterface
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import info.nightscout.androidaps.automation.R
|
|||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputString
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.TimerUtil
|
||||
|
@ -24,7 +23,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest
|
|||
import org.powermock.modules.junit4.PowerMockRunner
|
||||
|
||||
@RunWith(PowerMockRunner::class)
|
||||
@PrepareForTest(NSUpload::class, RxBusWrapper::class, TimerUtil::class)
|
||||
@PrepareForTest(RxBusWrapper::class, TimerUtil::class)
|
||||
class ActionAlarmTest : TestBase() {
|
||||
|
||||
@Mock lateinit var resourceHelper: ResourceHelper
|
||||
|
|
|
@ -6,11 +6,8 @@ import info.nightscout.androidaps.TestBase
|
|||
import info.nightscout.androidaps.automation.R
|
||||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction
|
||||
import info.nightscout.androidaps.database.transactions.Transaction
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputString
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import org.junit.Assert
|
||||
|
@ -21,12 +18,11 @@ import org.mockito.ArgumentMatchers
|
|||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.Mockito.any
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
||||
import org.powermock.modules.junit4.PowerMockRunner
|
||||
|
||||
@RunWith(PowerMockRunner::class)
|
||||
@PrepareForTest(NSUpload::class, RxBusWrapper::class)
|
||||
@PrepareForTest(RxBusWrapper::class)
|
||||
class ActionNotificationTest : TestBase() {
|
||||
|
||||
@Mock lateinit var resourceHelper: ResourceHelper
|
||||
|
|
|
@ -175,7 +175,7 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints {
|
|||
this.pumpSync = pumpSync;
|
||||
this.dateUtil = dateUtil;
|
||||
|
||||
pumpDescription.setPumpDescription(PumpType.ACCU_CHEK_COMBO);
|
||||
pumpDescription.fillFor(PumpType.ACCU_CHEK_COMBO);
|
||||
}
|
||||
|
||||
@Override protected void onStart() {
|
||||
|
|
|
@ -425,7 +425,7 @@ class TDDStatsActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
private fun isOldData(historyList: List<TotalDailyDose>): Boolean {
|
||||
val type = activePlugin.activePump.pumpDescription.pumpType
|
||||
val startsYesterday = type == PumpType.DANA_R || type == PumpType.DANA_RS || type == PumpType.DANA_RV2 || type == PumpType.DANA_R_KOREAN || type == PumpType.ACCU_CHEK_INSIGHT
|
||||
val startsYesterday = type == PumpType.DANA_R || type == PumpType.DANA_RS || type == PumpType.DANA_RV2 || type == PumpType.DANA_R_KOREAN || type == PumpType.ACCU_CHEK_INSIGHT_VIRTUAL
|
||||
val df: DateFormat = SimpleDateFormat("dd.MM.", Locale.getDefault())
|
||||
return historyList.size < 3 || df.format(Date(historyList[0].timestamp)) != df.format(Date(System.currentTimeMillis() - if (startsYesterday) 1000 * 60 * 60 * 24 else 0))
|
||||
}
|
||||
|
|
|
@ -1,728 +0,0 @@
|
|||
package info.nightscout.androidaps.data;
|
||||
|
||||
import static info.nightscout.androidaps.extensions.ProfileSwitchExtensionKt.pureProfileFromJson;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.collection.LongSparseArray;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.HasAndroidInjector;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.core.R;
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin;
|
||||
import info.nightscout.androidaps.interfaces.Config;
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit;
|
||||
import info.nightscout.androidaps.interfaces.Profile;
|
||||
import info.nightscout.androidaps.interfaces.Pump;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
|
||||
public class ProfileImplOld implements Profile {
|
||||
@Inject public AAPSLogger aapsLogger;
|
||||
@Inject public ActivePlugin activePlugin;
|
||||
@Inject public ResourceHelper resourceHelper;
|
||||
@Inject public RxBusWrapper rxBus;
|
||||
@Inject public FabricPrivacy fabricPrivacy;
|
||||
@Inject public Config config;
|
||||
@Inject public DateUtil dateUtil;
|
||||
|
||||
private final HasAndroidInjector injector;
|
||||
|
||||
private JSONObject json;
|
||||
private String jsonUnits;
|
||||
private double dia; // TODO change to insulinInterface link
|
||||
private TimeZone timeZone;
|
||||
private JSONArray isf;
|
||||
private LongSparseArray<Double> isf_v; // oldest at index 0
|
||||
private JSONArray ic;
|
||||
private LongSparseArray<Double> ic_v; // oldest at index 0
|
||||
private JSONArray basal;
|
||||
private LongSparseArray<Double> basal_v; // oldest at index 0
|
||||
private JSONArray targetLow;
|
||||
private LongSparseArray<Double> targetLow_v; // oldest at index 0
|
||||
private JSONArray targetHigh;
|
||||
private LongSparseArray<Double> targetHigh_v; // oldest at index 0
|
||||
|
||||
private int percentage;
|
||||
private int timeshift;
|
||||
|
||||
protected boolean isValid;
|
||||
protected boolean isValidated;
|
||||
|
||||
protected ProfileImplOld(HasAndroidInjector injector) {
|
||||
injector.androidInjector().inject(this);
|
||||
this.injector = injector;
|
||||
}
|
||||
|
||||
@NonNull @Override
|
||||
public String toString() {
|
||||
if (json != null)
|
||||
return json.toString();
|
||||
else
|
||||
return "Profile has no JSON";
|
||||
}
|
||||
|
||||
// Constructor from profileStore JSON
|
||||
public ProfileImplOld(HasAndroidInjector injector, JSONObject json, GlucoseUnit units) {
|
||||
this(injector);
|
||||
init(json, 100, 0);
|
||||
if (this.jsonUnits == null) {
|
||||
if (units != null)
|
||||
this.jsonUnits = units.getAsText();
|
||||
else {
|
||||
fabricPrivacy.logCustom("Profile failover failed too");
|
||||
this.jsonUnits = Constants.MGDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ProfileImplOld(HasAndroidInjector injector, JSONObject json, int percentage, int timeshift) {
|
||||
this(injector);
|
||||
init(json, percentage, timeshift);
|
||||
}
|
||||
|
||||
protected void init(JSONObject json, int percentage, int timeshift) {
|
||||
if (json == null) return;
|
||||
jsonUnits = null;
|
||||
dia = Constants.defaultDIA;
|
||||
timeZone = TimeZone.getDefault();
|
||||
isf_v = null;
|
||||
ic_v = null;
|
||||
basal_v = null;
|
||||
targetLow_v = null;
|
||||
targetHigh_v = null;
|
||||
|
||||
isValid = true;
|
||||
isValidated = false;
|
||||
|
||||
this.percentage = percentage;
|
||||
this.timeshift = timeshift;
|
||||
this.json = json;
|
||||
try {
|
||||
if (json.has("units"))
|
||||
jsonUnits = json.getString("units").toLowerCase();
|
||||
if (json.has("dia"))
|
||||
dia = json.getDouble("dia");
|
||||
if (json.has("timezone"))
|
||||
timeZone = TimeZone.getTimeZone(json.getString("timezone"));
|
||||
isf = json.getJSONArray("sens");
|
||||
ic = json.getJSONArray("carbratio");
|
||||
basal = json.getJSONArray("basal");
|
||||
targetLow = json.getJSONArray("target_low");
|
||||
targetHigh = json.getJSONArray("target_high");
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
isValid = false;
|
||||
isValidated = true;
|
||||
}
|
||||
}
|
||||
|
||||
public String log() {
|
||||
String ret = "\n";
|
||||
for (int hour = 0; hour < 24; hour++) {
|
||||
double value = getBasalTimeFromMidnight(hour * 60 * 60);
|
||||
ret += "NS basal value for " + hour + ":00 is " + value + "\n";
|
||||
}
|
||||
ret += "NS units: " + getUnits();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public JSONObject getData() {
|
||||
if (!json.has("units"))
|
||||
try {
|
||||
json.put("units", jsonUnits);
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public double getDia() {
|
||||
return dia;
|
||||
}
|
||||
|
||||
// mmol or mg/dl
|
||||
public void setUnits(String units) {
|
||||
this.jsonUnits = units;
|
||||
}
|
||||
|
||||
public GlucoseUnit getUnits() {
|
||||
if (jsonUnits.equals(Constants.MMOL)) return GlucoseUnit.MMOL;
|
||||
else return GlucoseUnit.MGDL;
|
||||
}
|
||||
|
||||
TimeZone getTimeZone() {
|
||||
return timeZone;
|
||||
}
|
||||
|
||||
private LongSparseArray<Double> convertToSparseArray(JSONArray array) {
|
||||
if (array == null) {
|
||||
isValid = false;
|
||||
return new LongSparseArray<>();
|
||||
}
|
||||
|
||||
double multiplier = getMultiplier(array);
|
||||
|
||||
LongSparseArray<Double> sparse = new LongSparseArray<>();
|
||||
for (int index = 0; index < array.length(); index++) {
|
||||
try {
|
||||
final JSONObject o = array.getJSONObject(index);
|
||||
long tas;
|
||||
try {
|
||||
String time = o.getString("time");
|
||||
tas = getShitfTimeSecs(dateUtil.toSeconds(time));
|
||||
} catch (JSONException e) {
|
||||
//log.debug(">>>>>>>>>>>> Used recalculated timeAsSeconds: " + time + " " + tas);
|
||||
tas = getShitfTimeSecs((int) o.getLong("timeAsSeconds"));
|
||||
}
|
||||
double value = o.getDouble("value") * multiplier;
|
||||
sparse.put(tas, value);
|
||||
} catch (Exception e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
aapsLogger.error(json.toString());
|
||||
fabricPrivacy.logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// check if start is at 0 (midnight)
|
||||
// and add last value before midnight if not
|
||||
if (sparse.keyAt(0) != 0) {
|
||||
sparse.put(0, sparse.valueAt(sparse.size() - 1));
|
||||
}
|
||||
return sparse;
|
||||
}
|
||||
|
||||
public synchronized boolean isValid(String from, Pump pump, Config config, ResourceHelper resourceHelper, RxBusWrapper rxBus) {
|
||||
if (!isValid)
|
||||
return false;
|
||||
if (!isValidated) {
|
||||
if (basal_v == null)
|
||||
basal_v = convertToSparseArray(basal);
|
||||
validate(basal_v);
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(isf);
|
||||
validate(isf_v);
|
||||
if (ic_v == null)
|
||||
ic_v = convertToSparseArray(ic);
|
||||
validate(ic_v);
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
validate(targetLow_v);
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
validate(targetHigh_v);
|
||||
|
||||
if (targetHigh_v.size() != targetLow_v.size()) isValid = false;
|
||||
else for (int i = 0; i < targetHigh_v.size(); i++)
|
||||
if (targetHigh_v.valueAt(i) < targetLow_v.valueAt(i))
|
||||
isValid = false;
|
||||
|
||||
isValidated = true;
|
||||
}
|
||||
|
||||
boolean notify = true;
|
||||
if (isValid) {
|
||||
// Check for hours alignment
|
||||
if (!pump.getPumpDescription().is30minBasalRatesCapable()) {
|
||||
for (int index = 0; index < basal_v.size(); index++) {
|
||||
long secondsFromMidnight = basal_v.keyAt(index);
|
||||
if (notify && secondsFromMidnight % 3600 != 0) {
|
||||
if (config.getAPS()) {
|
||||
Notification notification = new Notification(Notification.BASAL_PROFILE_NOT_ALIGNED_TO_HOURS, resourceHelper.gs(R.string.basalprofilenotaligned, from), Notification.NORMAL);
|
||||
rxBus.send(new EventNewNotification(notification));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for minimal basal value
|
||||
PumpDescription description = pump.getPumpDescription();
|
||||
for (int i = 0; i < basal_v.size(); i++) {
|
||||
if (basal_v.valueAt(i) < description.getBasalMinimumRate()) {
|
||||
basal_v.setValueAt(i, description.getBasalMinimumRate());
|
||||
if (notify)
|
||||
sendBelowMinimumNotification(from);
|
||||
} else if (basal_v.valueAt(i) > description.getBasalMaximumRate()) {
|
||||
basal_v.setValueAt(i, description.getBasalMaximumRate());
|
||||
if (notify)
|
||||
sendAboveMaximumNotification(from);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
protected void sendBelowMinimumNotification(String from) {
|
||||
rxBus.send(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, resourceHelper.gs(R.string.minimalbasalvaluereplaced, from), Notification.NORMAL)));
|
||||
}
|
||||
|
||||
protected void sendAboveMaximumNotification(String from) {
|
||||
rxBus.send(new EventNewNotification(new Notification(Notification.MAXIMUM_BASAL_VALUE_REPLACED, resourceHelper.gs(R.string.maximumbasalvaluereplaced, from), Notification.NORMAL)));
|
||||
}
|
||||
|
||||
private void validate(LongSparseArray array) {
|
||||
if (array.size() == 0) {
|
||||
isValid = false;
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < array.size(); index++) {
|
||||
if (array.valueAt(index).equals(0d)) {
|
||||
isValid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private Double getValueToTime(JSONArray array, Integer timeAsSeconds) {
|
||||
Double lastValue = null;
|
||||
|
||||
for (Integer index = 0; index < array.length(); index++) {
|
||||
try {
|
||||
JSONObject o = array.getJSONObject(index);
|
||||
Integer tas = o.getInt("timeAsSeconds");
|
||||
Double value = o.getDouble("value");
|
||||
if (lastValue == null) lastValue = value;
|
||||
if (timeAsSeconds < tas) {
|
||||
break;
|
||||
}
|
||||
lastValue = value;
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
return lastValue;
|
||||
}
|
||||
*/
|
||||
|
||||
Integer getShitfTimeSecs(Integer originalTime) {
|
||||
int shiftedTime = originalTime + timeshift * 60 * 60;
|
||||
shiftedTime = (shiftedTime + 24 * 60 * 60) % (24 * 60 * 60);
|
||||
return shiftedTime;
|
||||
}
|
||||
|
||||
private double getMultiplier(LongSparseArray<Double> array) {
|
||||
double multiplier = 1d;
|
||||
|
||||
if (array == isf_v)
|
||||
multiplier = 100d / percentage;
|
||||
else if (array == ic_v)
|
||||
multiplier = 100d / percentage;
|
||||
else if (array == basal_v)
|
||||
multiplier = percentage / 100d;
|
||||
else
|
||||
aapsLogger.error("Unknown array type");
|
||||
return multiplier;
|
||||
}
|
||||
|
||||
private double getMultiplier(JSONArray array) {
|
||||
double multiplier = 1d;
|
||||
|
||||
if (array == isf)
|
||||
multiplier = 100d / percentage;
|
||||
else if (array == ic)
|
||||
multiplier = 100d / percentage;
|
||||
else if (array == basal)
|
||||
multiplier = percentage / 100d;
|
||||
else if (array == targetLow)
|
||||
multiplier = 1d;
|
||||
else if (array == targetHigh)
|
||||
multiplier = 1d;
|
||||
else
|
||||
aapsLogger.error("Unknown array type");
|
||||
return multiplier;
|
||||
}
|
||||
|
||||
private double getValueToTime(LongSparseArray<Double> array, Integer timeAsSeconds) {
|
||||
Double lastValue = null;
|
||||
|
||||
for (int index = 0; index < array.size(); index++) {
|
||||
long tas = array.keyAt(index);
|
||||
double value = array.valueAt(index);
|
||||
if (lastValue == null) lastValue = value;
|
||||
if (timeAsSeconds < tas) {
|
||||
break;
|
||||
}
|
||||
lastValue = value;
|
||||
}
|
||||
return lastValue;
|
||||
}
|
||||
|
||||
private String getValuesList(LongSparseArray<Double> array, LongSparseArray<Double> array2, DecimalFormat format, String units) {
|
||||
String retValue = "";
|
||||
|
||||
for (Integer index = 0; index < array.size(); index++) {
|
||||
retValue += dateUtil.format_HH_MM((int) array.keyAt(index));
|
||||
retValue += " ";
|
||||
retValue += format.format(array.valueAt(index));
|
||||
if (array2 != null) {
|
||||
retValue += " - ";
|
||||
retValue += format.format(array2.valueAt(index));
|
||||
}
|
||||
retValue += " " + units;
|
||||
if (index + 1 < array.size())
|
||||
retValue += "\n";
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
public double getIsfMgdl() {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getIsfTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight()), getUnits());
|
||||
}
|
||||
|
||||
public double getIsfMgdl(long time) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getIsfTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight(time)), getUnits());
|
||||
}
|
||||
|
||||
public double getIsfMgdlTimeFromMidnight(int timeAsSeconds) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getIsfTimeFromMidnight(timeAsSeconds), getUnits());
|
||||
}
|
||||
|
||||
public double getIsfTimeFromMidnight(int timeAsSeconds) {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(isf);
|
||||
return getValueToTime(isf_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public String getIsfList(ResourceHelper resourceHelper, DateUtil dateUtil) {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(isf);
|
||||
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits().getAsText() + resourceHelper.gs(R.string.profile_per_unit));
|
||||
}
|
||||
|
||||
public ProfileValue[] getIsfsMgdlValues() {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(ic);
|
||||
ProfileValue[] ret = new ProfileValue[isf_v.size()];
|
||||
|
||||
for (int index = 0; index < isf_v.size(); index++) {
|
||||
int tas = (int) isf_v.keyAt(index);
|
||||
double value = isf_v.valueAt(index);
|
||||
ret[index] = new ProfileValue(tas, info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(value, getUnits()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public double getIc() {
|
||||
return getIcTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight());
|
||||
}
|
||||
|
||||
public double getIc(long time) {
|
||||
return getIcTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight(time));
|
||||
}
|
||||
|
||||
public double getIcTimeFromMidnight(int timeAsSeconds) {
|
||||
if (ic_v == null)
|
||||
ic_v = convertToSparseArray(ic);
|
||||
return getValueToTime(ic_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public String getIcList(ResourceHelper resourceHelper, DateUtil dateUtil) {
|
||||
if (ic_v == null)
|
||||
ic_v = convertToSparseArray(ic);
|
||||
return getValuesList(ic_v, null, new DecimalFormat("0.0"), resourceHelper.gs(R.string.profile_carbs_per_unit));
|
||||
}
|
||||
|
||||
public ProfileValue[] getIcsValues() {
|
||||
if (ic_v == null)
|
||||
ic_v = convertToSparseArray(ic);
|
||||
ProfileValue[] ret = new ProfileValue[ic_v.size()];
|
||||
|
||||
for (int index = 0; index < ic_v.size(); index++) {
|
||||
int tas = (int) ic_v.keyAt(index);
|
||||
double value = ic_v.valueAt(index);
|
||||
ret[index] = new ProfileValue(tas, value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public double getBasal() {
|
||||
return getBasalTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight());
|
||||
}
|
||||
|
||||
public double getBasal(long time) {
|
||||
return getBasalTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight(time));
|
||||
}
|
||||
|
||||
public synchronized double getBasalTimeFromMidnight(int timeAsSeconds) {
|
||||
if (basal_v == null) {
|
||||
basal_v = convertToSparseArray(basal);
|
||||
}
|
||||
return getValueToTime(basal_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public String getBasalList(ResourceHelper resourceHelper, DateUtil dateUtil) {
|
||||
if (basal_v == null)
|
||||
basal_v = convertToSparseArray(basal);
|
||||
return getValuesList(basal_v, null, new DecimalFormat("0.00"), resourceHelper.gs(R.string.profile_ins_units_per_hour));
|
||||
}
|
||||
|
||||
@NonNull @Override public JSONObject toPureNsJson(DateUtil dateUtil) {
|
||||
return getData();
|
||||
}
|
||||
|
||||
public synchronized ProfileValue[] getBasalValues() {
|
||||
if (basal_v == null)
|
||||
basal_v = convertToSparseArray(basal);
|
||||
ProfileValue[] ret = new ProfileValue[basal_v.size()];
|
||||
|
||||
for (int index = 0; index < basal_v.size(); index++) {
|
||||
int tas = (int) basal_v.keyAt(index);
|
||||
double value = basal_v.valueAt(index);
|
||||
ret[index] = new ProfileValue(tas, value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public double getTargetMgdl() {
|
||||
return getTargetMgdl(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight());
|
||||
}
|
||||
|
||||
public double getTargetMgdl(int timeAsSeconds) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl((getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds)) / 2, getUnits());
|
||||
}
|
||||
|
||||
public double getTargetLowMgdl() {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetLowTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight()), getUnits());
|
||||
}
|
||||
|
||||
public double getTargetLowMgdl(long time) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetLowTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight(time)), getUnits());
|
||||
}
|
||||
|
||||
double getTargetLowTimeFromMidnight(int timeAsSeconds) {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
return getValueToTime(targetLow_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public double getTargetLowMgdlTimeFromMidnight(int timeAsSeconds) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetLowTimeFromMidnight(timeAsSeconds), getUnits());
|
||||
}
|
||||
|
||||
public double getTargetHighMgdl() {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetHighTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight()), getUnits());
|
||||
}
|
||||
|
||||
public double getTargetHighMgdl(long time) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetHighTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight(time)), getUnits());
|
||||
}
|
||||
|
||||
public double getTargetHighTimeFromMidnight(int timeAsSeconds) {
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
return getValueToTime(targetHigh_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public double getTargetHighMgdlTimeFromMidnight(int timeAsSeconds) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetHighTimeFromMidnight(timeAsSeconds), getUnits());
|
||||
}
|
||||
|
||||
public static class TargetValue {
|
||||
TargetValue(int timeAsSeconds, double low, double high) {
|
||||
this.timeAsSeconds = timeAsSeconds;
|
||||
this.low = low;
|
||||
this.high = high;
|
||||
}
|
||||
|
||||
public int timeAsSeconds;
|
||||
public double low;
|
||||
public double high;
|
||||
}
|
||||
|
||||
public TargetValue[] getTargets() {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
TargetValue[] ret = new TargetValue[targetLow_v.size()];
|
||||
|
||||
for (int index = 0; index < targetLow_v.size(); index++) {
|
||||
int tas = (int) targetLow_v.keyAt(index);
|
||||
double low = targetLow_v.valueAt(index);
|
||||
double high = targetHigh_v.valueAt(index);
|
||||
ret[index] = new TargetValue(tas, low, high);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ProfileValue[] getSingleTargetsMgdl() {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
ProfileValue[] ret = new ProfileValue[targetLow_v.size()];
|
||||
|
||||
for (int index = 0; index < targetLow_v.size(); index++) {
|
||||
int tas = (int) targetLow_v.keyAt(index);
|
||||
double target = (targetLow_v.valueAt(index) + targetHigh_v.valueAt(index)) / 2;
|
||||
ret[index] = new ProfileValue(tas, info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(target, getUnits()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@NonNull public String getTargetList(ResourceHelper resourceHelper, DateUtil dateUtil) {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
return getValuesList(targetLow_v, targetHigh_v, new DecimalFormat("0.0"), getUnits().getAsText());
|
||||
}
|
||||
|
||||
public double getMaxDailyBasal() {
|
||||
double max = 0d;
|
||||
for (int hour = 0; hour < 24; hour++) {
|
||||
double value = getBasalTimeFromMidnight(hour * 60 * 60);
|
||||
if (value > max) max = value;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public double percentageBasalSum() {
|
||||
double result = 0d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
result += getBasalTimeFromMidnight(i * 60 * 60);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public double baseBasalSum() {
|
||||
double result = 0d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
result += getBasalTimeFromMidnight(i * 60 * 60) / getMultiplier(basal_v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getPercentage() {
|
||||
return percentage;
|
||||
}
|
||||
|
||||
public int getTimeshift() {
|
||||
return timeshift;
|
||||
}
|
||||
|
||||
public PureProfile convertToNonCustomizedProfile(DateUtil dateUtil) {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("units", jsonUnits);
|
||||
o.put("dia", dia);
|
||||
o.put("timezone", timeZone.getID());
|
||||
// SENS
|
||||
JSONArray sens = new JSONArray();
|
||||
double lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getIsfTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
sens.put(item);
|
||||
}
|
||||
}
|
||||
o.put("sens", sens);
|
||||
// CARBRATIO
|
||||
JSONArray carbratio = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getIcTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
carbratio.put(item);
|
||||
}
|
||||
}
|
||||
o.put("carbratio", carbratio);
|
||||
// BASAL
|
||||
JSONArray basal = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getBasalTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
basal.put(item);
|
||||
}
|
||||
}
|
||||
o.put("basal", basal);
|
||||
// TARGET_LOW
|
||||
JSONArray target_low = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getTargetLowTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
target_low.put(item);
|
||||
}
|
||||
}
|
||||
o.put("target_low", target_low);
|
||||
// TARGET_HIGH
|
||||
JSONArray target_high = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getTargetHighTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
target_high.put(item);
|
||||
}
|
||||
}
|
||||
o.put("target_high", target_high);
|
||||
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception" + e);
|
||||
}
|
||||
return pureProfileFromJson(o, dateUtil);
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package info.nightscout.androidaps.db;
|
||||
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
|
||||
@DatabaseTable(tableName = "DanaRHistory")
|
||||
public class DanaRHistoryRecord {
|
||||
|
||||
@DatabaseField
|
||||
public String _id;
|
||||
|
||||
@DatabaseField
|
||||
public byte recordCode;
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public String bytes;
|
||||
|
||||
@DatabaseField
|
||||
public long recordDate;
|
||||
|
||||
@DatabaseField
|
||||
public double recordValue;
|
||||
|
||||
@DatabaseField
|
||||
public String bolusType;
|
||||
|
||||
@DatabaseField
|
||||
public String stringRecordValue;
|
||||
|
||||
@DatabaseField
|
||||
public int recordDuration;
|
||||
|
||||
@DatabaseField
|
||||
public double recordDailyBasal;
|
||||
|
||||
@DatabaseField
|
||||
public double recordDailyBolus;
|
||||
|
||||
@DatabaseField
|
||||
public String recordAlarm;
|
||||
|
||||
public DanaRHistoryRecord() {
|
||||
this.recordDate = 0;
|
||||
this.recordValue = 0.0;
|
||||
this.bolusType = "None";
|
||||
this.recordCode = 0x0F;
|
||||
this.bytes = new String();
|
||||
this._id = null;
|
||||
}
|
||||
|
||||
public int getRecordLevel(double dExLow, double dLow, double dHigh, double dExHigh) {
|
||||
if (this.recordValue < dExLow)
|
||||
return 0;
|
||||
if (this.recordValue < dLow)
|
||||
return 1;
|
||||
if (this.recordValue < dHigh)
|
||||
return 2;
|
||||
return this.recordValue < dExHigh ? 3 : 4;
|
||||
}
|
||||
|
||||
public void setBytes(byte[] raw) {
|
||||
this.bytes = bytesToHex(raw);
|
||||
}
|
||||
|
||||
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
for (int j = 0; j < bytes.length; j++) {
|
||||
int v = bytes[j] & 0xFF;
|
||||
hexChars[j * 2] = hexArray[v >>> 4];
|
||||
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
||||
}
|
||||
return new String(hexChars);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
package info.nightscout.androidaps.db;
|
||||
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
/**
|
||||
* Created by mike on 27.02.2016.
|
||||
* <p>
|
||||
* Allowed actions "dbAdd" || "dbUpdate" || "dbUpdateUnset" || "dbRemove"
|
||||
*/
|
||||
@DatabaseTable(tableName = "DBRequests")
|
||||
public class DbRequest {
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public String nsClientID = null;
|
||||
|
||||
@DatabaseField
|
||||
public String action = null;
|
||||
|
||||
@DatabaseField
|
||||
public String collection = null;
|
||||
|
||||
@DatabaseField
|
||||
public String data = null;
|
||||
|
||||
@DatabaseField
|
||||
public String _id = null;
|
||||
|
||||
public DbRequest() {
|
||||
}
|
||||
|
||||
// dbAdd
|
||||
public DbRequest(String action, String collection, JSONObject json, long nsClientId) {
|
||||
this.action = action;
|
||||
this.collection = collection;
|
||||
this.nsClientID = "" + nsClientId;
|
||||
try {
|
||||
json.put("NSCLIENT_ID", nsClientID);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.data = json.toString();
|
||||
this._id = "";
|
||||
}
|
||||
|
||||
// dbUpdate, dbUpdateUnset
|
||||
public DbRequest(String action, String collection, String _id, JSONObject json, long nsClientId) {
|
||||
this.action = action;
|
||||
this.collection = collection;
|
||||
this.nsClientID = "" + nsClientId;
|
||||
try {
|
||||
json.put("NSCLIENT_ID", nsClientID);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.data = json.toString();
|
||||
this._id = _id;
|
||||
}
|
||||
|
||||
// dbRemove
|
||||
public DbRequest(String action, String collection, String _id, long nsClientId) {
|
||||
JSONObject json = new JSONObject();
|
||||
this.action = action;
|
||||
this.collection = collection;
|
||||
this.nsClientID = "" + nsClientId;
|
||||
try {
|
||||
json.put("NSCLIENT_ID", nsClientID);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.data = json.toString();
|
||||
this._id = _id;
|
||||
}
|
||||
|
||||
public String log() {
|
||||
return
|
||||
"\nnsClientID:" + nsClientID +
|
||||
"\naction:" + action +
|
||||
"\ncollection:" + collection +
|
||||
"\ndata:" + data +
|
||||
"\n_id:" + _id;
|
||||
}
|
||||
}
|
|
@ -2,29 +2,18 @@ package info.nightscout.androidaps.di
|
|||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.data.ProfileImplOld
|
||||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.db.ExtendedBolus
|
||||
import info.nightscout.androidaps.db.TemporaryBasal
|
||||
import info.nightscout.androidaps.db.Treatment
|
||||
import info.nightscout.androidaps.interfaces.ProfileStore
|
||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class CoreDataClassesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun nsMbgInjector(): NSMbg
|
||||
|
||||
@ContributesAndroidInjector abstract fun pumpEnactResultInjector(): PumpEnactResult
|
||||
@ContributesAndroidInjector abstract fun apsResultInjector(): APSResult
|
||||
@ContributesAndroidInjector abstract fun autosensDataInjector(): AutosensData
|
||||
|
||||
@ContributesAndroidInjector abstract fun profileInjector(): ProfileImplOld
|
||||
@ContributesAndroidInjector abstract fun profileStoreInjector(): ProfileStore
|
||||
@ContributesAndroidInjector abstract fun treatmentInjector(): Treatment
|
||||
@ContributesAndroidInjector abstract fun temporaryBasalInjector(): TemporaryBasal
|
||||
@ContributesAndroidInjector abstract fun extendedBolusInjector(): ExtendedBolus
|
||||
}
|
||||
|
|
|
@ -4,14 +4,9 @@ import android.content.Context
|
|||
import android.preference.PreferenceManager
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.AAPSLoggerProduction
|
||||
import info.nightscout.androidaps.logging.L
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelperImplementation
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
|
@ -25,12 +20,6 @@ import javax.inject.Singleton
|
|||
])
|
||||
open class CoreModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideProfileFunction(aapsLogger: AAPSLogger, sp: SP, resourceHelper: ResourceHelper, activePlugin: ActivePlugin, repository: AppRepository, dateUtil: DateUtil): ProfileFunction {
|
||||
return ProfileFunctionImplementation(aapsLogger, sp, resourceHelper, activePlugin, repository, dateUtil)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideResources(context: Context): ResourceHelper = ResourceHelperImplementation(context)
|
||||
|
|
|
@ -5,7 +5,6 @@ import info.nightscout.androidaps.database.data.TargetBlock
|
|||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
|
||||
private fun getShiftedTimeSecs(originalSeconds: Int, timeShiftHours: Int): Int {
|
||||
|
@ -86,33 +85,18 @@ fun blockFromJsonArray(jsonArray: JSONArray?, dateUtil: DateUtil): List<Block>?
|
|||
val ret = ArrayList<Block>(size)
|
||||
try {
|
||||
for (index in 0 until jsonArray.length() - 1) {
|
||||
val o: JSONObject = jsonArray.getJSONObject(index)
|
||||
val tas: Int = try {
|
||||
o.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = o.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val next: JSONObject = jsonArray.getJSONObject(index + 1)
|
||||
val nextTas: Int = try {
|
||||
next.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = next.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val value: Double = o.getDouble("value")
|
||||
val o = jsonArray.getJSONObject(index)
|
||||
val tas = dateUtil.toSeconds(o.getString("time"))
|
||||
val next = jsonArray.getJSONObject(index + 1)
|
||||
val nextTas = dateUtil.toSeconds(next.getString("time"))
|
||||
val value = o.getDouble("value")
|
||||
if (tas % 3600 != 0) return null
|
||||
if (nextTas % 3600 != 0) return null
|
||||
ret.add(index, Block((nextTas - tas) * 1000L, value))
|
||||
}
|
||||
val last: JSONObject = jsonArray.getJSONObject(jsonArray.length() - 1)
|
||||
val lastTas: Int = try {
|
||||
last.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = last.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val value: Double = last.getDouble("value")
|
||||
val lastTas = dateUtil.toSeconds(last.getString("time"))
|
||||
val value = last.getDouble("value")
|
||||
ret.add(jsonArray.length() - 1, Block((T.hours(24).secs() - lastTas) * 1000L, value))
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
|
@ -128,41 +112,23 @@ fun targetBlockFromJsonArray(jsonArray1: JSONArray?, jsonArray2: JSONArray?, dat
|
|||
try {
|
||||
for (index in 0 until jsonArray1.length() - 1) {
|
||||
val o1: JSONObject = jsonArray1.getJSONObject(index)
|
||||
val tas1: Int = try {
|
||||
o1.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = o1.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val value1: Double = o1.getDouble("value")
|
||||
val next1: JSONObject = jsonArray1.getJSONObject(index + 1)
|
||||
val nextTas1: Int = try {
|
||||
next1.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = next1.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val o2: JSONObject = jsonArray2.getJSONObject(index)
|
||||
val tas2: Int = try {
|
||||
o2.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = o2.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val value2: Double = o2.getDouble("value")
|
||||
val tas1 = dateUtil.toSeconds(o1.getString("time"))
|
||||
val value1 = o1.getDouble("value")
|
||||
val next1 = jsonArray1.getJSONObject(index + 1)
|
||||
val nextTas1 = dateUtil.toSeconds(next1.getString("time"))
|
||||
val o2 = jsonArray2.getJSONObject(index)
|
||||
val tas2 = dateUtil.toSeconds(o2.getString("time"))
|
||||
val value2 = o2.getDouble("value")
|
||||
if (tas1 != tas2) return null
|
||||
if (tas1 % 3600 != 0) return null
|
||||
if (nextTas1 % 3600 != 0) return null
|
||||
ret.add(index, TargetBlock((nextTas1 - tas1) * 1000L, value1, value2))
|
||||
}
|
||||
val last1: JSONObject = jsonArray1.getJSONObject(jsonArray1.length() - 1)
|
||||
val lastTas1: Int = try {
|
||||
last1.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = last1.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val value1: Double = last1.getDouble("value")
|
||||
val last2: JSONObject = jsonArray2.getJSONObject(jsonArray2.length() - 1)
|
||||
val value2: Double = last2.getDouble("value")
|
||||
val last1 = jsonArray1.getJSONObject(jsonArray1.length() - 1)
|
||||
val lastTas1 = dateUtil.toSeconds(last1.getString("time"))
|
||||
val value1 = last1.getDouble("value")
|
||||
val last2 = jsonArray2.getJSONObject(jsonArray2.length() - 1)
|
||||
val value2 = last2.getDouble("value")
|
||||
ret.add(jsonArray1.length() - 1, TargetBlock((T.hours(24).secs() - lastTas1) * 1000L, value1, value2))
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
|
|
|
@ -85,6 +85,7 @@ fun extendedBolusFromNsIdForInvalidating(nsId: String): ExtendedBolus =
|
|||
JSONObject()
|
||||
.put("mills", 1)
|
||||
.put("amount", -1.0)
|
||||
.put("enteredinsulin", -1.0)
|
||||
.put("duration", -1.0)
|
||||
.put("splitNow", 0)
|
||||
.put("splitExt", 100)
|
||||
|
|
|
@ -7,6 +7,7 @@ import info.nightscout.androidaps.database.embedments.InterfaceIDs
|
|||
import info.nightscout.androidaps.database.entities.ProfileSwitch
|
||||
import info.nightscout.androidaps.database.entities.TemporaryBasal
|
||||
import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
|
@ -23,7 +24,7 @@ fun ProfileSwitch.toJson(dateUtil: DateUtil): JSONObject =
|
|||
.put("eventType", TherapyEvent.Type.PROFILE_SWITCH.text)
|
||||
.put("duration", T.msecs(duration).mins())
|
||||
.put("profile", getCustomizedName())
|
||||
.put("profileJson", ProfileSealed.PS(this).toPureNsJson(dateUtil))
|
||||
.put("profileJson", ProfileSealed.PS(this).toPureNsJson(dateUtil).toString())
|
||||
.put("timeshift", T.msecs(timeshift).hours())
|
||||
.put("percentage", percentage)
|
||||
.also {
|
||||
|
@ -33,7 +34,20 @@ fun ProfileSwitch.toJson(dateUtil: DateUtil): JSONObject =
|
|||
if (interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId)
|
||||
}
|
||||
|
||||
fun profileSwitchFromJson(jsonObject: JSONObject, dateUtil: DateUtil): ProfileSwitch? {
|
||||
/* NS PS
|
||||
{
|
||||
"_id":"608ffa268db0676196a772d7",
|
||||
"enteredBy":"undefined",
|
||||
"eventType":"Profile Switch",
|
||||
"duration":10,
|
||||
"profile":"LocalProfile0",
|
||||
"created_at":"2021-05-03T13:26:58.537Z",
|
||||
"utcOffset":0,
|
||||
"mills":1620048418537,
|
||||
"mgdl":98
|
||||
}
|
||||
*/
|
||||
fun profileSwitchFromJson(jsonObject: JSONObject, dateUtil: DateUtil, activePlugin: ActivePlugin): ProfileSwitch? {
|
||||
val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
|
||||
val duration = JsonHelper.safeGetLong(jsonObject, "duration")
|
||||
val timeshift = JsonHelper.safeGetLong(jsonObject, "timeshift")
|
||||
|
@ -41,15 +55,21 @@ fun profileSwitchFromJson(jsonObject: JSONObject, dateUtil: DateUtil): ProfileSw
|
|||
val isValid = JsonHelper.safeGetBoolean(jsonObject, "isValid", true)
|
||||
val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", null)
|
||||
val profileName = JsonHelper.safeGetStringAllowNull(jsonObject, "profile", null) ?: return null
|
||||
val profileJson = JsonHelper.safeGetStringAllowNull(jsonObject, "profileJson", null) ?: return null
|
||||
val profileJson = JsonHelper.safeGetStringAllowNull(jsonObject, "profileJson", null)
|
||||
val pumpId = JsonHelper.safeGetLongAllowNull(jsonObject, "pumpId", null)
|
||||
val pumpType = InterfaceIDs.PumpType.fromString(JsonHelper.safeGetStringAllowNull(jsonObject, "pumpType", null))
|
||||
val pumpSerial = JsonHelper.safeGetStringAllowNull(jsonObject, "pumpSerial", null)
|
||||
|
||||
if (timestamp == 0L) return null
|
||||
val pureProfile = pureProfileFromJson(JSONObject(profileJson), dateUtil) ?: return null
|
||||
val pureProfile =
|
||||
if (profileJson == null) { // entered through NS, no JSON attached
|
||||
val profilePlugin = activePlugin.activeProfileSource
|
||||
val store = profilePlugin.profile ?: return null
|
||||
store.getSpecificProfile(profileName) ?: return null
|
||||
} else pureProfileFromJson(JSONObject(profileJson), dateUtil) ?: return null
|
||||
val profileSealed = ProfileSealed.Pure(pureProfile)
|
||||
|
||||
|
||||
return ProfileSwitch(
|
||||
timestamp = timestamp,
|
||||
basalBlocks = profileSealed.basalBlocks,
|
||||
|
@ -74,9 +94,9 @@ fun profileSwitchFromJson(jsonObject: JSONObject, dateUtil: DateUtil): ProfileSw
|
|||
/**
|
||||
* Pure profile doesn't contain timestamp, percentage, timeshift, profileName
|
||||
*/
|
||||
fun pureProfileFromJson(jsonObject: JSONObject, dateUtil: DateUtil): PureProfile? {
|
||||
fun pureProfileFromJson(jsonObject: JSONObject, dateUtil: DateUtil, defaultUnits: String? = null): PureProfile? {
|
||||
try {
|
||||
JsonHelper.safeGetStringAllowNull(jsonObject, "units", null) ?: return null
|
||||
JsonHelper.safeGetStringAllowNull(jsonObject, "units", defaultUnits) ?: return null
|
||||
val units = GlucoseUnit.fromText(JsonHelper.safeGetString(jsonObject, "units", Constants.MGDL))
|
||||
val dia = JsonHelper.safeGetDoubleAllowNull(jsonObject, "dia") ?: return null
|
||||
val timezone = TimeZone.getTimeZone(JsonHelper.safeGetString(jsonObject, "timezone", "UTC"))
|
||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.androidaps.interfaces
|
|||
|
||||
import info.nightscout.androidaps.database.entities.DeviceStatus
|
||||
import info.nightscout.androidaps.database.entities.*
|
||||
import org.json.JSONObject
|
||||
|
||||
interface DataSyncSelector {
|
||||
|
||||
|
@ -15,6 +16,9 @@ interface DataSyncSelector {
|
|||
data class PairTemporaryBasal(val value: TemporaryBasal, val updateRecordId: Long)
|
||||
data class PairExtendedBolus(val value: ExtendedBolus, val updateRecordId: Long)
|
||||
data class PairProfileSwitch(val value: ProfileSwitch, val updateRecordId: Long)
|
||||
data class PairProfileStore(val value: JSONObject, val timestampSync: Long)
|
||||
|
||||
fun doUpload()
|
||||
|
||||
fun resetToNextFullSync()
|
||||
|
||||
|
@ -72,4 +76,7 @@ interface DataSyncSelector {
|
|||
fun changedProfileSwitch() : List<ProfileSwitch>
|
||||
// Until NS v3
|
||||
fun processChangedProfileSwitchesCompat(): Boolean
|
||||
|
||||
fun confirmLastProfileStore(lastSynced: Long)
|
||||
fun processChangedProfileStore()
|
||||
}
|
|
@ -1,28 +1,17 @@
|
|||
package info.nightscout.androidaps.interfaces
|
||||
|
||||
import com.j256.ormlite.dao.CloseableIterator
|
||||
import info.nightscout.androidaps.db.*
|
||||
import org.json.JSONObject
|
||||
|
||||
interface DatabaseHelperInterface {
|
||||
|
||||
fun resetDatabases()
|
||||
|
||||
fun createOrUpdate(record: DanaRHistoryRecord)
|
||||
fun createOrUpdate(record: OmnipodHistoryRecord)
|
||||
fun createOrUpdate(record: InsightBolusID)
|
||||
fun createOrUpdate(record: InsightPumpID)
|
||||
fun createOrUpdate(record: InsightHistoryOffset)
|
||||
fun createOrUpdate(record: OHQueueItem)
|
||||
fun create(record: DbRequest)
|
||||
fun getDanaRHistoryRecordsByType(type: Byte): List<DanaRHistoryRecord>
|
||||
fun size(table: String): Long
|
||||
fun deleteAllDbRequests()
|
||||
fun deleteDbRequest(id: String): Int
|
||||
fun delete(extendedBolus: ExtendedBolus)
|
||||
fun deleteDbRequestbyMongoId(action: String, _id: String)
|
||||
fun getDbRequestIterator(): CloseableIterator<DbRequest>
|
||||
fun roundDateToSec(date: Long): Long
|
||||
fun createOrUpdate(tempBasal: TemporaryBasal): Boolean
|
||||
@Deprecated("Use new DB")
|
||||
fun findTempBasalByPumpId(id: Long): TemporaryBasal?
|
||||
|
@ -41,7 +30,6 @@ interface DatabaseHelperInterface {
|
|||
|
||||
fun getOHQueueSize(): Long
|
||||
fun clearOpenHumansQueue()
|
||||
fun getCountOfAllRows(): Long
|
||||
fun removeAllOHQueueItemsWithIdSmallerThan(id: Long)
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -20,7 +20,7 @@ interface IobCobCalculator {
|
|||
fun getLastAutosensDataWithWaitForCalculationFinish(reason: String): AutosensData?
|
||||
|
||||
fun calculateAbsInsulinFromTreatmentsAndTemps(fromTime: Long): IobTotal
|
||||
fun calculateFromTreatmentsAndTemps(time: Long, profile: Profile): IobTotal
|
||||
fun calculateFromTreatmentsAndTemps(fromTime: Long, profile: Profile): IobTotal
|
||||
|
||||
fun getBasalData(profile: Profile, fromTime: Long): BasalData
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package info.nightscout.androidaps.interfaces
|
|||
|
||||
import androidx.collection.ArrayMap
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.data.ProfileImplOld
|
||||
import info.nightscout.androidaps.data.PureProfile
|
||||
import info.nightscout.androidaps.extensions.pureProfileFromJson
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
|
@ -53,12 +52,13 @@ class ProfileStore(val injector: HasAndroidInjector, val data: JSONObject, val d
|
|||
|
||||
fun getSpecificProfile(profileName: String): PureProfile? {
|
||||
var profile: PureProfile? = null
|
||||
val defaultUnits = JsonHelper.safeGetStringAllowNull(data, "units", null)
|
||||
getStore()?.let { store ->
|
||||
if (store.has(profileName)) {
|
||||
profile = cachedObjects[profileName]
|
||||
if (profile == null) {
|
||||
JsonHelper.safeGetJSONObject(store, profileName, null)?.let { profileObject ->
|
||||
profile = pureProfileFromJson(profileObject, dateUtil)
|
||||
profile = pureProfileFromJson(profileObject, dateUtil, defaultUnits)
|
||||
cachedObjects[profileName] = profile
|
||||
}
|
||||
}
|
||||
|
@ -67,8 +67,7 @@ class ProfileStore(val injector: HasAndroidInjector, val data: JSONObject, val d
|
|||
return profile
|
||||
}
|
||||
|
||||
fun getSpecificProfileJson(profileName: String): JSONObject? {
|
||||
var profile: PureProfile? = null
|
||||
private fun getSpecificProfileJson(profileName: String): JSONObject? {
|
||||
getStore()?.let { store ->
|
||||
if (store.has(profileName))
|
||||
return JsonHelper.safeGetJSONObject(store, profileName, null)
|
||||
|
|
|
@ -7,7 +7,7 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
|||
class PumpDescription() {
|
||||
|
||||
constructor(pumpType: PumpType) : this() {
|
||||
setPumpDescription(pumpType)
|
||||
fillFor(pumpType)
|
||||
}
|
||||
|
||||
var pumpType = PumpType.GENERIC_AAPS
|
||||
|
@ -69,7 +69,7 @@ class PumpDescription() {
|
|||
hasCustomUnreachableAlertCheck = false
|
||||
}
|
||||
|
||||
fun setPumpDescription(pumpType: PumpType) {
|
||||
fun fillFor(pumpType: PumpType) {
|
||||
resetSettings()
|
||||
this.pumpType = pumpType
|
||||
val pumpCapability = pumpType.pumpCapability ?: return
|
||||
|
|
|
@ -344,6 +344,19 @@ interface PumpSync {
|
|||
**/
|
||||
fun invalidateTemporaryBasal(id: Long): Boolean
|
||||
|
||||
/**
|
||||
* Invalidate of temporary basals that failed to start
|
||||
* MDT specific
|
||||
*
|
||||
* If exists, isValid is set false
|
||||
* If db record doesn't exist data is ignored and false returned
|
||||
*
|
||||
*
|
||||
* @param temporaryId temporary id of temporary basal
|
||||
* @return true if running record is found and invalidated
|
||||
**/
|
||||
fun invalidateTemporaryBasalWithTempId(temporaryId: Long): Boolean
|
||||
|
||||
/**
|
||||
* Synchronization of extended bolus
|
||||
*
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
package info.nightscout.androidaps.interfaces
|
||||
|
||||
interface UploadQueueAdminInterface : UploadQueueInterface {
|
||||
|
||||
fun clearQueue()
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package info.nightscout.androidaps.interfaces;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import info.nightscout.androidaps.db.DbRequest;
|
||||
|
||||
public interface UploadQueueInterface {
|
||||
|
||||
long size();
|
||||
|
||||
void add(DbRequest dbRequest);
|
||||
|
||||
void removeByMongoId(final String action, final String _id);
|
||||
|
||||
String textList();
|
||||
}
|
|
@ -48,7 +48,6 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
|
|||
var usePercent = false
|
||||
var duration = 0
|
||||
var tempBasalRequested = false
|
||||
var bolusRequested = false
|
||||
var iob: IobTotal? = null
|
||||
var json: JSONObject? = JSONObject()
|
||||
var hasPredictions = false
|
||||
|
@ -161,7 +160,6 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
|
|||
newResult.rate = rate
|
||||
newResult.duration = duration
|
||||
newResult.tempBasalRequested = tempBasalRequested
|
||||
newResult.bolusRequested = bolusRequested
|
||||
newResult.iob = iob
|
||||
newResult.json = JSONObject(json.toString())
|
||||
newResult.hasPredictions = hasPredictions
|
||||
|
@ -309,11 +307,11 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
|
|||
// closed loop mode: handle change at driver level
|
||||
if (closedLoopEnabled.value()) {
|
||||
aapsLogger.debug(LTag.APS, "DEFAULT: Closed mode")
|
||||
return tempBasalRequested || bolusRequested
|
||||
return tempBasalRequested || bolusRequested()
|
||||
}
|
||||
|
||||
// open loop mode: try to limit request
|
||||
if (!tempBasalRequested && !bolusRequested) {
|
||||
if (!tempBasalRequested && !bolusRequested()) {
|
||||
aapsLogger.debug(LTag.APS, "FALSE: No request")
|
||||
return false
|
||||
}
|
||||
|
@ -399,4 +397,6 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun bolusRequested(): Boolean = smb > 0.0
|
||||
}
|
|
@ -82,7 +82,7 @@ class RunningConfiguration @Inject constructor(
|
|||
if (configuration.has("pump")) {
|
||||
val pumpType = JsonHelper.safeGetString(configuration, "pump", PumpType.GENERIC_AAPS.description)
|
||||
sp.putString(R.string.key_virtualpump_type, pumpType)
|
||||
activePlugin.activePump.pumpDescription.setPumpDescription(PumpType.getByDescription(pumpType))
|
||||
activePlugin.activePump.pumpDescription.fillFor(PumpType.getByDescription(pumpType))
|
||||
aapsLogger.debug(LTag.CORE, "Changing pump type to $pumpType")
|
||||
}
|
||||
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.nsclient;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import info.nightscout.androidaps.core.R;
|
||||
import info.nightscout.androidaps.db.DbRequest;
|
||||
import info.nightscout.androidaps.interfaces.UploadQueueInterface;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 26.05.2017.
|
||||
*/
|
||||
@Singleton
|
||||
public class NSUpload {
|
||||
|
||||
private final AAPSLogger aapsLogger;
|
||||
private final SP sp;
|
||||
private final UploadQueueInterface uploadQueue;
|
||||
|
||||
@Inject
|
||||
public NSUpload(
|
||||
AAPSLogger aapsLogger,
|
||||
SP sp,
|
||||
UploadQueueInterface uploadQueue
|
||||
) {
|
||||
this.aapsLogger = aapsLogger;
|
||||
this.sp = sp;
|
||||
this.uploadQueue = uploadQueue;
|
||||
}
|
||||
/*
|
||||
public void uploadProfileSwitch(ProfileSwitch profileSwitch, long nsClientId, DateUtil dateUtil) {
|
||||
try {
|
||||
JSONObject data = getJson(profileSwitch, dateUtil);
|
||||
DbRequest dbr = new DbRequest("dbAdd", "treatments", data, nsClientId);
|
||||
aapsLogger.debug("Prepared: " + dbr.log());
|
||||
uploadQueue.add(dbr);
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateProfileSwitch(ProfileSwitch profileSwitch, DateUtil dateUtil) {
|
||||
try {
|
||||
JSONObject data = getJson(profileSwitch, dateUtil);
|
||||
if (profileSwitch._id != null) {
|
||||
uploadQueue.add(new DbRequest("dbUpdate", "treatments", profileSwitch._id, data, profileSwitch.date));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static JSONObject getJson(ProfileSwitch profileSwitch, DateUtil dateUtil) throws JSONException {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("eventType", TherapyEvent.Type.PROFILE_SWITCH.getText());
|
||||
data.put("duration", profileSwitch.durationInMinutes);
|
||||
data.put("profile", profileSwitch.getCustomizedName());
|
||||
data.put("profileJson", profileSwitch.profileJson);
|
||||
data.put("profilePlugin", profileSwitch.profilePlugin);
|
||||
if (profileSwitch.isCPP) {
|
||||
data.put("CircadianPercentageProfile", true);
|
||||
data.put("timeshift", profileSwitch.timeshift);
|
||||
data.put("percentage", profileSwitch.percentage);
|
||||
}
|
||||
data.put("created_at", dateUtil.toISOString(profileSwitch.date));
|
||||
data.put("enteredBy", "AndroidAPS");
|
||||
|
||||
return data;
|
||||
}
|
||||
*/
|
||||
// TODO replace with setting isValid = false
|
||||
public void removeCareportalEntryFromNS(String _id) {
|
||||
uploadQueue.add(new DbRequest("dbRemove", "treatments", _id, System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
public void uploadProfileStore(JSONObject profileStore) {
|
||||
if (sp.getBoolean(R.string.key_ns_uploadlocalprofile, false)) {
|
||||
uploadQueue.add(new DbRequest("dbAdd", "profile", profileStore, System.currentTimeMillis()));
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isIdValid(String _id) {
|
||||
if (_id == null)
|
||||
return false;
|
||||
return _id.length() == 24;
|
||||
}
|
||||
|
||||
}
|
|
@ -330,6 +330,18 @@ class PumpSyncImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun invalidateTemporaryBasalWithTempId(temporaryId: Long): Boolean {
|
||||
repository.runTransactionForResult(InvalidateTemporaryBasalWithTempIdTransaction(temporaryId))
|
||||
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while invalidating TemporaryBasal", it) }
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.invalidated.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryBasal $it")
|
||||
}
|
||||
return result.invalidated.size > 0
|
||||
}
|
||||
}
|
||||
|
||||
override fun syncExtendedBolusWithPumpId(timestamp: Long, amount: Double, duration: Long, isEmulatingTB: Boolean, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
|
||||
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
|
||||
val extendedBolus = ExtendedBolus(
|
||||
|
|
|
@ -64,7 +64,7 @@ enum class PumpType {
|
|||
baseBasalStep = 0.1,
|
||||
baseBasalSpecialSteps = null,
|
||||
pumpCapability = PumpCapability.VirtualPumpCapabilities),
|
||||
ACCU_CHEK_INSIGHT(description = "Accu-Chek Insight",
|
||||
ACCU_CHEK_INSIGHT_VIRTUAL(description = "Accu-Chek Insight",
|
||||
manufacturer = ManufacturerType.Roche,
|
||||
model = "Insight",
|
||||
bolusSize = 0.05,
|
||||
|
@ -77,7 +77,7 @@ enum class PumpType {
|
|||
baseBasalStep = 0.01,
|
||||
baseBasalSpecialSteps = null,
|
||||
pumpCapability = PumpCapability.InsightCapabilities),
|
||||
ACCU_CHEK_INSIGHT_BLUETOOTH(description = "Accu-Chek Insight",
|
||||
ACCU_CHEK_INSIGHT(description = "Accu-Chek Insight",
|
||||
manufacturer = ManufacturerType.Roche,
|
||||
model = "Insight",
|
||||
bolusSize = 0.01,
|
||||
|
@ -89,7 +89,7 @@ enum class PumpType {
|
|||
baseBasalMinValue = 0.02,
|
||||
baseBasalMaxValue = null,
|
||||
baseBasalStep = 0.01,
|
||||
baseBasalSpecialSteps = DoseStepSize.InsightBolus,
|
||||
baseBasalSpecialSteps = DoseStepSize.InsightBasal,
|
||||
pumpCapability = PumpCapability.InsightCapabilities),
|
||||
ACCU_CHEK_SOLO(description = "Accu-Chek Solo",
|
||||
manufacturer = ManufacturerType.Roche,
|
||||
|
@ -418,9 +418,9 @@ enum class PumpType {
|
|||
CELLNOVO -> InterfaceIDs.PumpType.CELLNOVO
|
||||
ACCU_CHEK_COMBO -> InterfaceIDs.PumpType.ACCU_CHEK_COMBO
|
||||
ACCU_CHEK_SPIRIT -> InterfaceIDs.PumpType.ACCU_CHEK_SPIRIT
|
||||
ACCU_CHEK_INSIGHT -> InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT
|
||||
ACCU_CHEK_INSIGHT_BLUETOOTH -> InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT_BLUETOOTH
|
||||
ACCU_CHEK_SOLO -> InterfaceIDs.PumpType.ACCU_CHEK_SOLO
|
||||
ACCU_CHEK_INSIGHT_VIRTUAL -> InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT
|
||||
ACCU_CHEK_INSIGHT -> InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT_BLUETOOTH
|
||||
ACCU_CHEK_SOLO -> InterfaceIDs.PumpType.ACCU_CHEK_SOLO
|
||||
ANIMAS_VIBE -> InterfaceIDs.PumpType.ANIMAS_VIBE
|
||||
ANIMAS_PING -> InterfaceIDs.PumpType.ANIMAS_PING
|
||||
DANA_R -> InterfaceIDs.PumpType.DANA_R
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
<string name="key_high_mark" translatable="false">high_mark</string>
|
||||
<string name="key_ns_create_announcements_from_errors" translatable="false">ns_create_announcements_from_errors</string>
|
||||
<string name="key_ns_logappstartedevent" translatable="false">ns_logappstartedevent</string>
|
||||
<string name="key_ns_uploadlocalprofile" translatable="false">ns_uploadlocalprofile</string>
|
||||
<string name="key_btwatchdog" translatable="false">bt_watchdog</string>
|
||||
<string name="key_btwatchdog_lastbark" translatable="false">bt_watchdog_last</string>
|
||||
<string name="key_pump_unreachable_threshold_minutes" translatable="false">pump_unreachable_threshold</string>
|
||||
|
|
|
@ -10,7 +10,7 @@ class PumpDescriptionTest {
|
|||
|
||||
@Test fun setPumpDescription() {
|
||||
val pumpDescription = PumpDescription()
|
||||
pumpDescription.setPumpDescription(PumpType.ACCU_CHEK_COMBO)
|
||||
pumpDescription.fillFor(PumpType.ACCU_CHEK_COMBO)
|
||||
Assert.assertEquals(pumpDescription.bolusStep, PumpType.ACCU_CHEK_COMBO.bolusSize, 0.1)
|
||||
Assert.assertEquals(pumpDescription.basalMinimumRate, PumpType.ACCU_CHEK_COMBO.baseBasalStep, 0.1)
|
||||
Assert.assertEquals(pumpDescription.basalStep, PumpType.ACCU_CHEK_COMBO.baseBasalStep, 0.1)
|
||||
|
|
|
@ -51,7 +51,7 @@ class APSResultTest : TestBaseWithProfile() {
|
|||
// BASAL RATE IN TEST PROFILE IS 1U/h
|
||||
|
||||
// **** PERCENT pump ****
|
||||
testPumpPlugin.pumpDescription.setPumpDescription(PumpType.CELLNOVO) // % based
|
||||
testPumpPlugin.pumpDescription.fillFor(PumpType.CELLNOVO) // % based
|
||||
apsResult.usePercent(true)
|
||||
|
||||
// closed loop mode return original request
|
||||
|
@ -109,7 +109,7 @@ class APSResultTest : TestBaseWithProfile() {
|
|||
Assert.assertEquals(true, apsResult.isChangeRequested)
|
||||
|
||||
// **** ABSOLUTE pump ****
|
||||
testPumpPlugin.pumpDescription.setPumpDescription(PumpType.MEDTRONIC_515_715) // U/h based
|
||||
testPumpPlugin.pumpDescription.fillFor(PumpType.MEDTRONIC_515_715) // U/h based
|
||||
apsResult.usePercent(false)
|
||||
|
||||
// open loop
|
||||
|
|
|
@ -12,9 +12,21 @@ android {
|
|||
defaultConfig {
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
kapt {
|
||||
arguments {
|
||||
arg("room.incremental", "true")
|
||||
arg("room.schemaLocation", "$projectDir/schemas")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':core')
|
||||
|
||||
api "androidx.room:room-ktx:$room_version"
|
||||
api "androidx.room:room-runtime:$room_version"
|
||||
api "androidx.room:room-rxjava2:$room_version"
|
||||
kapt "androidx.room:room-compiler:$room_version"
|
||||
kapt "android.arch.persistence.room:compiler:$room_version"
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "04f2e440fae2d62ca4e4a38840b5cf2f",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "danaHistory",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`timestamp` INTEGER NOT NULL, `code` INTEGER NOT NULL, `value` REAL NOT NULL, `bolusType` TEXT NOT NULL, `stringValue` TEXT NOT NULL, `duration` INTEGER NOT NULL, `dailyBasal` REAL NOT NULL, `dailyBolus` REAL NOT NULL, `alarm` TEXT NOT NULL, PRIMARY KEY(`timestamp`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "timestamp",
|
||||
"columnName": "timestamp",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "code",
|
||||
"columnName": "code",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "value",
|
||||
"columnName": "value",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "bolusType",
|
||||
"columnName": "bolusType",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "stringValue",
|
||||
"columnName": "stringValue",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "duration",
|
||||
"columnName": "duration",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dailyBasal",
|
||||
"columnName": "dailyBasal",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dailyBolus",
|
||||
"columnName": "dailyBolus",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "alarm",
|
||||
"columnName": "alarm",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"timestamp"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_danaHistory_code_timestamp",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"code",
|
||||
"timestamp"
|
||||
],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_danaHistory_code_timestamp` ON `${TABLE_NAME}` (`code`, `timestamp`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '04f2e440fae2d62ca4e4a38840b5cf2f')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -6,21 +6,21 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
|
||||
import info.nightscout.androidaps.dana.R
|
||||
import info.nightscout.androidaps.dana.comm.RecordTypes
|
||||
import info.nightscout.androidaps.dana.database.DanaHistoryRecord
|
||||
import info.nightscout.androidaps.dana.database.DanaHistoryRecordDao
|
||||
import info.nightscout.androidaps.dana.databinding.DanarHistoryActivityBinding
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.db.DanaRHistoryRecord
|
||||
import info.nightscout.androidaps.dana.databinding.DanarHistoryItemBinding
|
||||
import info.nightscout.androidaps.events.EventDanaRSyncStatus
|
||||
import info.nightscout.androidaps.events.EventPumpStatusChanged
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
|
@ -30,6 +30,7 @@ import info.nightscout.androidaps.queue.Callback
|
|||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
|
@ -44,14 +45,13 @@ class DanaHistoryActivity : NoSplashAppCompatActivity() {
|
|||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var commandQueue: CommandQueueProvider
|
||||
@Inject lateinit var databaseHelper: DatabaseHelperInterface
|
||||
@Inject lateinit var danaHistoryRecordDao: DanaHistoryRecordDao
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private var showingType = RecordTypes.RECORD_TYPE_ALARM
|
||||
private var historyList: List<DanaRHistoryRecord> = ArrayList()
|
||||
|
||||
class TypeList internal constructor(var type: Byte, var name: String) {
|
||||
|
||||
|
@ -73,6 +73,7 @@ class DanaHistoryActivity : NoSplashAppCompatActivity() {
|
|||
aapsLogger.debug(LTag.PUMP, "EventDanaRSyncStatus: " + it.message)
|
||||
binding.status.text = it.message
|
||||
}, fabricPrivacy::logException)
|
||||
swapAdapter(showingType)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
|
@ -87,7 +88,6 @@ class DanaHistoryActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(this)
|
||||
binding.recyclerview.adapter = RecyclerViewAdapter(historyList)
|
||||
binding.status.visibility = View.GONE
|
||||
|
||||
val pump = activePlugin.activePump
|
||||
|
@ -115,14 +115,12 @@ class DanaHistoryActivity : NoSplashAppCompatActivity() {
|
|||
binding.reload.setOnClickListener {
|
||||
val selected = binding.spinner.selectedItem as TypeList?
|
||||
?: return@setOnClickListener
|
||||
runOnUiThread {
|
||||
binding.reload.visibility = View.GONE
|
||||
binding.status.visibility = View.VISIBLE
|
||||
}
|
||||
binding.reload.visibility = View.GONE
|
||||
binding.status.visibility = View.VISIBLE
|
||||
clearCardView()
|
||||
commandQueue.loadHistory(selected.type, object : Callback() {
|
||||
override fun run() {
|
||||
loadDataFromDB(selected.type)
|
||||
swapAdapter(selected.type)
|
||||
runOnUiThread {
|
||||
binding.reload.visibility = View.VISIBLE
|
||||
binding.status.visibility = View.GONE
|
||||
|
@ -133,7 +131,7 @@ class DanaHistoryActivity : NoSplashAppCompatActivity() {
|
|||
binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
val selected = typeList[position]
|
||||
loadDataFromDB(selected.type)
|
||||
swapAdapter(selected.type)
|
||||
showingType = selected.type
|
||||
}
|
||||
|
||||
|
@ -143,95 +141,95 @@ class DanaHistoryActivity : NoSplashAppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
inner class RecyclerViewAdapter internal constructor(private var historyList: List<DanaRHistoryRecord>) : RecyclerView.Adapter<RecyclerViewAdapter.HistoryViewHolder>() {
|
||||
inner class RecyclerViewAdapter internal constructor(private var historyList: List<DanaHistoryRecord>) : RecyclerView.Adapter<RecyclerViewAdapter.HistoryViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): HistoryViewHolder =
|
||||
HistoryViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.danar_history_item, viewGroup, false))
|
||||
|
||||
override fun onBindViewHolder(holder: HistoryViewHolder, position: Int) {
|
||||
val record = historyList[position]
|
||||
holder.time.text = dateUtil.dateAndTimeString(record.recordDate)
|
||||
holder.value.text = DecimalFormatter.to2Decimal(record.recordValue)
|
||||
holder.stringValue.text = record.stringRecordValue
|
||||
holder.bolusType.text = record.bolusType
|
||||
holder.duration.text = DecimalFormatter.to0Decimal(record.recordDuration.toDouble())
|
||||
holder.alarm.text = record.recordAlarm
|
||||
holder.binding.time.text = dateUtil.dateAndTimeString(record.timestamp)
|
||||
holder.binding.value.text = DecimalFormatter.to2Decimal(record.value)
|
||||
holder.binding.stringValue.text = record.stringValue
|
||||
holder.binding.bolusType.text = record.bolusType
|
||||
holder.binding.duration.text = record.duration.toString()
|
||||
holder.binding.alarm.text = record.alarm
|
||||
when (showingType) {
|
||||
RecordTypes.RECORD_TYPE_ALARM -> {
|
||||
holder.time.visibility = View.VISIBLE
|
||||
holder.value.visibility = View.VISIBLE
|
||||
holder.stringValue.visibility = View.GONE
|
||||
holder.bolusType.visibility = View.GONE
|
||||
holder.duration.visibility = View.GONE
|
||||
holder.dailyBasal.visibility = View.GONE
|
||||
holder.dailyBolus.visibility = View.GONE
|
||||
holder.dailyTotal.visibility = View.GONE
|
||||
holder.alarm.visibility = View.VISIBLE
|
||||
RecordTypes.RECORD_TYPE_ALARM -> {
|
||||
holder.binding.time.visibility = View.VISIBLE
|
||||
holder.binding.value.visibility = View.VISIBLE
|
||||
holder.binding.stringValue.visibility = View.GONE
|
||||
holder.binding.bolusType.visibility = View.GONE
|
||||
holder.binding.duration.visibility = View.GONE
|
||||
holder.binding.dailyBasal.visibility = View.GONE
|
||||
holder.binding.dailyBolus.visibility = View.GONE
|
||||
holder.binding.dailyTotal.visibility = View.GONE
|
||||
holder.binding.alarm.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
RecordTypes.RECORD_TYPE_BOLUS -> {
|
||||
holder.time.visibility = View.VISIBLE
|
||||
holder.value.visibility = View.VISIBLE
|
||||
holder.stringValue.visibility = View.GONE
|
||||
holder.bolusType.visibility = View.VISIBLE
|
||||
holder.duration.visibility = View.VISIBLE
|
||||
holder.dailyBasal.visibility = View.GONE
|
||||
holder.dailyBolus.visibility = View.GONE
|
||||
holder.dailyTotal.visibility = View.GONE
|
||||
holder.alarm.visibility = View.GONE
|
||||
RecordTypes.RECORD_TYPE_BOLUS -> {
|
||||
holder.binding.time.visibility = View.VISIBLE
|
||||
holder.binding.value.visibility = View.VISIBLE
|
||||
holder.binding.stringValue.visibility = View.GONE
|
||||
holder.binding.bolusType.visibility = View.VISIBLE
|
||||
holder.binding.duration.visibility = View.VISIBLE
|
||||
holder.binding.dailyBasal.visibility = View.GONE
|
||||
holder.binding.dailyBolus.visibility = View.GONE
|
||||
holder.binding.dailyTotal.visibility = View.GONE
|
||||
holder.binding.alarm.visibility = View.GONE
|
||||
}
|
||||
|
||||
RecordTypes.RECORD_TYPE_DAILY -> {
|
||||
holder.dailyBasal.text = resourceHelper.gs(R.string.formatinsulinunits, record.recordDailyBasal)
|
||||
holder.dailyBolus.text = resourceHelper.gs(R.string.formatinsulinunits, record.recordDailyBolus)
|
||||
holder.dailyTotal.text = resourceHelper.gs(R.string.formatinsulinunits, record.recordDailyBolus + record.recordDailyBasal)
|
||||
holder.time.text = dateUtil.dateString(record.recordDate)
|
||||
holder.time.visibility = View.VISIBLE
|
||||
holder.value.visibility = View.GONE
|
||||
holder.stringValue.visibility = View.GONE
|
||||
holder.bolusType.visibility = View.GONE
|
||||
holder.duration.visibility = View.GONE
|
||||
holder.dailyBasal.visibility = View.VISIBLE
|
||||
holder.dailyBolus.visibility = View.VISIBLE
|
||||
holder.dailyTotal.visibility = View.VISIBLE
|
||||
holder.alarm.visibility = View.GONE
|
||||
RecordTypes.RECORD_TYPE_DAILY -> {
|
||||
holder.binding.dailyBasal.text = resourceHelper.gs(R.string.formatinsulinunits, record.dailyBasal)
|
||||
holder.binding.dailyBolus.text = resourceHelper.gs(R.string.formatinsulinunits, record.dailyBolus)
|
||||
holder.binding.dailyTotal.text = resourceHelper.gs(R.string.formatinsulinunits, record.dailyBolus + record.dailyBasal)
|
||||
holder.binding.time.text = dateUtil.dateString(record.timestamp)
|
||||
holder.binding.time.visibility = View.VISIBLE
|
||||
holder.binding.value.visibility = View.GONE
|
||||
holder.binding.stringValue.visibility = View.GONE
|
||||
holder.binding.bolusType.visibility = View.GONE
|
||||
holder.binding.duration.visibility = View.GONE
|
||||
holder.binding.dailyBasal.visibility = View.VISIBLE
|
||||
holder.binding.dailyBolus.visibility = View.VISIBLE
|
||||
holder.binding.dailyTotal.visibility = View.VISIBLE
|
||||
holder.binding.alarm.visibility = View.GONE
|
||||
}
|
||||
|
||||
RecordTypes.RECORD_TYPE_GLUCOSE -> {
|
||||
holder.value.text = Profile.toUnitsString(record.recordValue, record.recordValue * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
|
||||
holder.time.visibility = View.VISIBLE
|
||||
holder.value.visibility = View.VISIBLE
|
||||
holder.stringValue.visibility = View.GONE
|
||||
holder.bolusType.visibility = View.GONE
|
||||
holder.duration.visibility = View.GONE
|
||||
holder.dailyBasal.visibility = View.GONE
|
||||
holder.dailyBolus.visibility = View.GONE
|
||||
holder.dailyTotal.visibility = View.GONE
|
||||
holder.alarm.visibility = View.GONE
|
||||
RecordTypes.RECORD_TYPE_GLUCOSE -> {
|
||||
holder.binding.value.text = Profile.toUnitsString(record.value, record.value * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
|
||||
holder.binding.time.visibility = View.VISIBLE
|
||||
holder.binding.value.visibility = View.VISIBLE
|
||||
holder.binding.stringValue.visibility = View.GONE
|
||||
holder.binding.bolusType.visibility = View.GONE
|
||||
holder.binding.duration.visibility = View.GONE
|
||||
holder.binding.dailyBasal.visibility = View.GONE
|
||||
holder.binding.dailyBolus.visibility = View.GONE
|
||||
holder.binding.dailyTotal.visibility = View.GONE
|
||||
holder.binding.alarm.visibility = View.GONE
|
||||
}
|
||||
|
||||
RecordTypes.RECORD_TYPE_CARBO, RecordTypes.RECORD_TYPE_BASALHOUR, RecordTypes.RECORD_TYPE_ERROR, RecordTypes.RECORD_TYPE_PRIME, RecordTypes.RECORD_TYPE_REFILL, RecordTypes.RECORD_TYPE_TB -> {
|
||||
holder.time.visibility = View.VISIBLE
|
||||
holder.value.visibility = View.VISIBLE
|
||||
holder.stringValue.visibility = View.GONE
|
||||
holder.bolusType.visibility = View.GONE
|
||||
holder.duration.visibility = View.GONE
|
||||
holder.dailyBasal.visibility = View.GONE
|
||||
holder.dailyBolus.visibility = View.GONE
|
||||
holder.dailyTotal.visibility = View.GONE
|
||||
holder.alarm.visibility = View.GONE
|
||||
holder.binding.time.visibility = View.VISIBLE
|
||||
holder.binding.value.visibility = View.VISIBLE
|
||||
holder.binding.stringValue.visibility = View.GONE
|
||||
holder.binding.bolusType.visibility = View.GONE
|
||||
holder.binding.duration.visibility = View.GONE
|
||||
holder.binding.dailyBasal.visibility = View.GONE
|
||||
holder.binding.dailyBolus.visibility = View.GONE
|
||||
holder.binding.dailyTotal.visibility = View.GONE
|
||||
holder.binding.alarm.visibility = View.GONE
|
||||
}
|
||||
|
||||
RecordTypes.RECORD_TYPE_SUSPEND -> {
|
||||
holder.time.visibility = View.VISIBLE
|
||||
holder.value.visibility = View.GONE
|
||||
holder.stringValue.visibility = View.VISIBLE
|
||||
holder.bolusType.visibility = View.GONE
|
||||
holder.duration.visibility = View.GONE
|
||||
holder.dailyBasal.visibility = View.GONE
|
||||
holder.dailyBolus.visibility = View.GONE
|
||||
holder.dailyTotal.visibility = View.GONE
|
||||
holder.alarm.visibility = View.GONE
|
||||
RecordTypes.RECORD_TYPE_SUSPEND -> {
|
||||
holder.binding.time.visibility = View.VISIBLE
|
||||
holder.binding.value.visibility = View.GONE
|
||||
holder.binding.stringValue.visibility = View.VISIBLE
|
||||
holder.binding.bolusType.visibility = View.GONE
|
||||
holder.binding.duration.visibility = View.GONE
|
||||
holder.binding.dailyBasal.visibility = View.GONE
|
||||
holder.binding.dailyBolus.visibility = View.GONE
|
||||
holder.binding.dailyTotal.visibility = View.GONE
|
||||
holder.binding.alarm.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -242,25 +240,17 @@ class DanaHistoryActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
inner class HistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
var time: TextView = itemView.findViewById(R.id.danar_history_time)
|
||||
var value: TextView = itemView.findViewById(R.id.danar_history_value)
|
||||
var bolusType: TextView = itemView.findViewById(R.id.danar_history_bolustype)
|
||||
var stringValue: TextView = itemView.findViewById(R.id.danar_history_stringvalue)
|
||||
var duration: TextView = itemView.findViewById(R.id.danar_history_duration)
|
||||
var dailyBasal: TextView = itemView.findViewById(R.id.danar_history_dailybasal)
|
||||
var dailyBolus: TextView = itemView.findViewById(R.id.danar_history_dailybolus)
|
||||
var dailyTotal: TextView = itemView.findViewById(R.id.danar_history_dailytotal)
|
||||
var alarm: TextView = itemView.findViewById(R.id.danar_history_alarm)
|
||||
val binding = DanarHistoryItemBinding.bind(itemView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadDataFromDB(type: Byte) {
|
||||
historyList = databaseHelper.getDanaRHistoryRecordsByType(type)
|
||||
runOnUiThread { binding.recyclerview.swapAdapter(RecyclerViewAdapter(historyList), false) }
|
||||
private fun swapAdapter(type: Byte) {
|
||||
disposable += danaHistoryRecordDao
|
||||
.allFromByType(dateUtil.now() - T.months(1).msecs(), type)
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { historyList -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(historyList), false) }
|
||||
}
|
||||
|
||||
private fun clearCardView() {
|
||||
historyList = ArrayList()
|
||||
runOnUiThread { binding.recyclerview.swapAdapter(RecyclerViewAdapter(historyList), false) }
|
||||
}
|
||||
private fun clearCardView() = binding.recyclerview.swapAdapter(RecyclerViewAdapter(ArrayList()), false)
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package info.nightscout.androidaps.dana.database
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
|
||||
const val TABLE_DANA_HISTORY = "danaHistory"
|
||||
|
||||
@Database(
|
||||
entities = [DanaHistoryRecord::class],
|
||||
exportSchema = true,
|
||||
version = DanaHistoryDatabase.VERSION
|
||||
)
|
||||
abstract class DanaHistoryDatabase : RoomDatabase() {
|
||||
|
||||
abstract fun historyRecordDao(): DanaHistoryRecordDao
|
||||
|
||||
companion object {
|
||||
|
||||
const val VERSION = 1
|
||||
|
||||
fun build(context: Context) =
|
||||
Room.databaseBuilder(
|
||||
context.applicationContext,
|
||||
DanaHistoryDatabase::class.java,
|
||||
"dana_database.db"
|
||||
)
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package info.nightscout.androidaps.dana.database
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = TABLE_DANA_HISTORY,
|
||||
indices = [Index("code", "timestamp")])
|
||||
data class DanaHistoryRecord(
|
||||
@PrimaryKey var timestamp: Long,
|
||||
var code: Byte = 0x0F,
|
||||
var value: Double = 0.0,
|
||||
var bolusType: String = "None",
|
||||
var stringValue: String = "",
|
||||
var duration: Long = 0,
|
||||
var dailyBasal: Double = 0.0,
|
||||
var dailyBolus: Double = 0.0,
|
||||
var alarm: String = ""
|
||||
)
|
|
@ -0,0 +1,17 @@
|
|||
package info.nightscout.androidaps.dana.database
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.reactivex.Single
|
||||
|
||||
@Dao
|
||||
abstract class DanaHistoryRecordDao {
|
||||
|
||||
@Query("SELECT * from $TABLE_DANA_HISTORY WHERE timestamp >= :timestamp AND code = :type")
|
||||
abstract fun allFromByType(timestamp: Long, type: Byte): Single<List<DanaHistoryRecord>>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract fun createOrUpdate(danaHistoryRecord: DanaHistoryRecord)
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package info.nightscout.androidaps.dana.di
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import info.nightscout.androidaps.dana.database.DanaHistoryDatabase
|
||||
import info.nightscout.androidaps.dana.database.DanaHistoryRecordDao
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
class DanaHistoryModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
internal fun provideDatabase(context: Context): DanaHistoryDatabase = DanaHistoryDatabase.build(context)
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
internal fun provideHistoryRecordDao(danaHistoryDatabase: DanaHistoryDatabase): DanaHistoryRecordDao =
|
||||
danaHistoryDatabase.historyRecordDao()
|
||||
}
|
|
@ -1,10 +1,15 @@
|
|||
package info.nightscout.androidaps.dana.di
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.dana.DanaFragment
|
||||
import info.nightscout.androidaps.dana.activities.DanaHistoryActivity
|
||||
import info.nightscout.androidaps.dana.activities.DanaUserOptionsActivity
|
||||
import info.nightscout.androidaps.dana.database.DanaHistoryDatabase
|
||||
import info.nightscout.androidaps.dana.database.DanaHistoryRecordDao
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
|
|
|
@ -1,94 +1,110 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/relativeLayout"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
tools:context="info.nightscout.androidaps.dana.activities.DanaHistoryActivity">
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@color/activity_title_background"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dp">
|
||||
android:padding="5dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/spinner"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/pumphistory"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_danarhistory" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:text="@string/pumphistory"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</RelativeLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/spacer"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/header"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dp" />
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:text="@string/eventtype"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/spinner"
|
||||
app:layout_constraintEnd_toStartOf="@+id/spinner"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/spinner" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/spinner_layout"
|
||||
android:layout_width="match_parent"
|
||||
<Spinner
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/spacer"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:text="@string/eventtype"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="20dp" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_marginEnd="10dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/status"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/textView"
|
||||
app:layout_constraintTop_toBottomOf="@+id/header" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/spinner_layout"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center_horizontal" />
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:gravity="center_horizontal"
|
||||
app:layout_constraintBottom_toTopOf="@+id/recyclerview"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@id/reload"
|
||||
android:layout_below="@+id/status" />
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/reload"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/status" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/reload"
|
||||
style="@style/Widget.AppCompat.Button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="1dp"
|
||||
android:drawableStart="@drawable/ic_actions_refill"
|
||||
android:text="@string/reload" />
|
||||
android:text="@string/reload"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/recyclerview" />
|
||||
|
||||
</RelativeLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -1,89 +1,109 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/danar_history_cardview"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
card_view:cardBackgroundColor="@color/cardColorBackground"
|
||||
card_view:cardCornerRadius="6dp"
|
||||
card_view:cardUseCompatPadding="true"
|
||||
card_view:contentPadding="6dp">
|
||||
card_view:cardBackgroundColor="?android:colorBackground">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:baselineAligned="true"
|
||||
android:orientation="horizontal">
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:baselineAligned="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/danar_history_time"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp"
|
||||
android:text="27.06.2016 18:00" />
|
||||
<TextView
|
||||
android:id="@+id/time"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp"
|
||||
android:text="27.06.2016 18:00"
|
||||
tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/danar_history_value"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp"
|
||||
android:text="0.25"
|
||||
android:gravity="right" />
|
||||
<TextView
|
||||
android:id="@+id/value"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:paddingLeft="5dp"
|
||||
android:text="0.25"
|
||||
tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/danar_history_bolustype"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp"
|
||||
android:text="E"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/bolus_type"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp"
|
||||
android:text="E"
|
||||
tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/danar_history_stringvalue"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp"
|
||||
android:text="XXXXXXX"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/string_value"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp"
|
||||
android:text=""
|
||||
tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/danar_history_duration"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp"
|
||||
android:text="30"
|
||||
android:gravity="right" />
|
||||
<TextView
|
||||
android:id="@+id/duration"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:paddingLeft="5dp"
|
||||
android:text="30"
|
||||
tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/danar_history_dailybasal"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp"
|
||||
android:gravity="right" />
|
||||
<TextView
|
||||
android:id="@+id/daily_basal"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:paddingLeft="5dp"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/danar_history_dailybolus"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp"
|
||||
android:gravity="right" />
|
||||
<TextView
|
||||
android:id="@+id/daily_bolus"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:paddingLeft="5dp"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/danar_history_dailytotal"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="10dp"
|
||||
android:gravity="right"
|
||||
android:visibility="gone"/>
|
||||
<TextView
|
||||
android:id="@+id/daily_total"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:paddingLeft="10dp"
|
||||
android:visibility="gone"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/danar_history_alarm"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp" />
|
||||
<TextView
|
||||
android:id="@+id/alarm"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="5dp"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@color/list_delimiter" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class DanaRKoreanPlugin @Inject constructor(
|
|||
init {
|
||||
pluginDescription.description(R.string.description_pump_dana_r_korean)
|
||||
useExtendedBoluses = sp.getBoolean(R.string.key_danar_useextended, false)
|
||||
pumpDescription.setPumpDescription(PumpType.DANA_R_KOREAN)
|
||||
pumpDescription.fillFor(PumpType.DANA_R_KOREAN)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
|
|
@ -194,7 +194,6 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService {
|
|||
|
||||
rxBus.send(new EventDanaRNewStatus());
|
||||
rxBus.send(new EventInitializationChanged());
|
||||
//NSUpload.uploadDeviceStatus();
|
||||
if (danaPump.getDailyTotalUnits() > danaPump.getMaxDailyTotalUnits() * Constants.dailyLimitWarning) {
|
||||
aapsLogger.debug(LTag.PUMP, "Approaching daily limit: " + danaPump.getDailyTotalUnits() + "/" + danaPump.getMaxDailyTotalUnits());
|
||||
if (System.currentTimeMillis() > lastApproachingDailyLimit + 30 * 60 * 1000) {
|
||||
|
|
|
@ -85,7 +85,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
|
|||
getPluginDescription().description(R.string.description_pump_dana_r_v2);
|
||||
|
||||
useExtendedBoluses = false;
|
||||
pumpDescription.setPumpDescription(PumpType.DANA_RV2);
|
||||
pumpDescription.fillFor(PumpType.DANA_RV2);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -231,7 +231,6 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
|
|||
|
||||
rxBus.send(new EventDanaRNewStatus());
|
||||
rxBus.send(new EventInitializationChanged());
|
||||
//NSUpload.uploadDeviceStatus();
|
||||
if (danaPump.getDailyTotalUnits() > danaPump.getMaxDailyTotalUnits() * Constants.dailyLimitWarning) {
|
||||
aapsLogger.debug(LTag.PUMP, "Approaching daily limit: " + danaPump.getDailyTotalUnits() + "/" + danaPump.getMaxDailyTotalUnits());
|
||||
if (System.currentTimeMillis() > lastApproachingDailyLimit + 30 * 60 * 1000) {
|
||||
|
|
|
@ -74,7 +74,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
|
|||
this.fabricPrivacy = fabricPrivacy;
|
||||
|
||||
useExtendedBoluses = sp.getBoolean(R.string.key_danar_useextended, false);
|
||||
pumpDescription.setPumpDescription(PumpType.DANA_R);
|
||||
pumpDescription.fillFor(PumpType.DANA_R);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue