Merge remote-tracking branch 'Nightscout/dev' into UE_VWU_DevMerge

# Conflicts:
#	app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt
#	app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt
#	app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt
#	app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt
#	app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt
#	app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientPlugin.java
#	app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsCareportalFragment.kt
#	app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt
#	database/schemas/info.nightscout.androidaps.database.AppDatabase/4.json
This commit is contained in:
Philoul 2021-03-09 21:50:17 +01:00
commit f3787304f8
158 changed files with 2328 additions and 4299 deletions

View file

@ -2,22 +2,6 @@
<code_scheme name="Project" version="173">
<option name="AUTODETECT_INDENTS" value="false" />
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" alias="false" withSubpackages="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
<package name="io.ktor" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="6" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="6" />

View file

@ -111,7 +111,7 @@ android {
defaultConfig {
multiDexEnabled true
versionCode 1500
version "2.8.2.1-dev-c"
version "2.8.2.1-dev-d"
buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'

View file

@ -3,9 +3,10 @@ package info.nightscout.androidaps.db
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.interfaces.TraceableDBEntry
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.events.EventNewBG
import info.nightscout.androidaps.events.EventTempTargetChange
import info.nightscout.androidaps.events.EventTherapyEventChange
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -39,5 +40,9 @@ class CompatDBHelper @Inject constructor(
aapsLogger.debug(LTag.DATABASE, "Firing EventTempTargetChange")
rxBus.send(EventTempTargetChange())
}
it.filterIsInstance<TherapyEvent>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventTherapyEventChange")
rxBus.send(EventTherapyEventChange())
}
}
}

View file

@ -33,9 +33,7 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import info.nightscout.androidaps.dana.comm.RecordTypes;
import info.nightscout.androidaps.data.NonOverlappingIntervals;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.events.EventCareportalEventChange;
import info.nightscout.androidaps.events.EventExtendedBolusChange;
import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
import info.nightscout.androidaps.events.EventRefreshOverview;
@ -74,7 +72,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public static final String DATABASE_EXTENDEDBOLUSES = "ExtendedBoluses";
public static final String DATABASE_DANARHISTORY = "DanaRHistory";
public static final String DATABASE_DBREQUESTS = "DBRequests";
public static final String DATABASE_CAREPORTALEVENTS = "CareportalEvents";
public static final String DATABASE_TDDS = "TDDs";
private static final int DATABASE_VERSION = 13;
@ -87,9 +84,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
private static final ScheduledExecutorService extendedBolusWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledExtendedBolusPost = null;
private static final ScheduledExecutorService careportalEventWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledCareportalEventPost = null;
private static final ScheduledExecutorService profileSwitchEventWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledProfileSwitchEventPost = null;
@ -111,7 +105,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
TableUtils.createTableIfNotExists(connectionSource, TemporaryBasal.class);
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
TableUtils.createTableIfNotExists(connectionSource, TDD.class);
TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class);
@ -141,7 +134,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.dropTable(connectionSource, DbRequest.class, true);
TableUtils.dropTable(connectionSource, TemporaryBasal.class, true);
TableUtils.dropTable(connectionSource, ExtendedBolus.class, true);
TableUtils.dropTable(connectionSource, CareportalEvent.class, true);
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
onCreate(database, connectionSource);
} else if (oldVersion < 10) {
@ -189,7 +181,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.dropTable(connectionSource, DbRequest.class, true);
TableUtils.dropTable(connectionSource, TemporaryBasal.class, true);
TableUtils.dropTable(connectionSource, ExtendedBolus.class, true);
TableUtils.dropTable(connectionSource, CareportalEvent.class, true);
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
TableUtils.dropTable(connectionSource, TDD.class, true);
TableUtils.dropTable(connectionSource, OmnipodHistoryRecord.class, true);
@ -197,7 +188,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
TableUtils.createTableIfNotExists(connectionSource, TemporaryBasal.class);
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
TableUtils.createTableIfNotExists(connectionSource, TDD.class);
TableUtils.createTableIfNotExists(connectionSource, OmnipodHistoryRecord.class);
@ -208,7 +198,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
virtualPumpPlugin.setFakingStatus(true);
scheduleTemporaryBasalChange();
scheduleExtendedBolusChange();
scheduleCareportalEventChange();
scheduleProfileSwitchChange();
new java.util.Timer().schedule(
new java.util.TimerTask() {
@ -244,16 +233,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
scheduleExtendedBolusChange();
}
public void resetCareportalEvents() {
try {
TableUtils.dropTable(connectionSource, CareportalEvent.class, true);
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
scheduleCareportalEventChange();
}
public void resetProfileSwitch() {
try {
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
@ -295,10 +274,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return getDao(ExtendedBolus.class);
}
private Dao<CareportalEvent, Long> getDaoCareportalEvents() throws SQLException {
return getDao(CareportalEvent.class);
}
private Dao<ProfileSwitch, Long> getDaoProfileSwitch() throws SQLException {
return getDao(ProfileSwitch.class);
}
@ -411,14 +386,20 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
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);
}
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);
}
@ -1033,219 +1014,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
// ------------ CareportalEvent handling ---------------
public void createOrUpdate(CareportalEvent careportalEvent) {
careportalEvent.date = careportalEvent.date - careportalEvent.date % 1000;
try {
getDaoCareportalEvents().createOrUpdate(careportalEvent);
openHumansUploader.enqueueCareportalEvent(careportalEvent);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
scheduleCareportalEventChange();
}
public void delete(CareportalEvent careportalEvent) {
try {
getDaoCareportalEvents().delete(careportalEvent);
openHumansUploader.enqueueCareportalEvent(careportalEvent, true);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
scheduleCareportalEventChange();
}
public CareportalEvent getCareportalEventFromTimestamp(long timestamp) {
try {
return getDaoCareportalEvents().queryForId(timestamp);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return null;
}
public List<CareportalEvent> getAllCareportalEvents() {
try {
return getDaoCareportalEvents().queryForAll();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return Collections.emptyList();
}
@Nullable
public CareportalEvent getLastCareportalEvent(String event) {
try {
List<CareportalEvent> careportalEvents;
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
queryBuilder.orderBy("date", false);
Where where = queryBuilder.where();
where.eq("eventType", event).and().isNotNull("json");
queryBuilder.limit(1L);
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
if (careportalEvents.size() == 1)
return careportalEvents.get(0);
else
return null;
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return null;
}
public List<CareportalEvent> getCareportalEventsFromTime(long mills, boolean ascending) {
try {
List<CareportalEvent> careportalEvents;
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.ge("date", mills).and().isNotNull("json").and().isNotNull("eventType");
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
return careportalEvents;
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public List<CareportalEvent> getCareportalEvents(long start, long end, boolean ascending) {
try {
List<CareportalEvent> careportalEvents;
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.between("date", start, end).and().isNotNull("json").and().isNotNull("eventType");
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
return careportalEvents;
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public List<CareportalEvent> preprocessOpenAPSOfflineEvents(List<CareportalEvent> list) {
NonOverlappingIntervals offlineEvents = new NonOverlappingIntervals();
List<CareportalEvent> other = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
CareportalEvent event = list.get(i);
if (event.eventType.equals(CareportalEvent.OPENAPSOFFLINE)) offlineEvents.add(event);
else other.add(event);
}
other.addAll(offlineEvents.getList());
return other;
}
public List<CareportalEvent> getCareportalEventsFromTime(long mills, String type, boolean ascending) {
try {
List<CareportalEvent> careportalEvents;
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.ge("date", mills).and().eq("eventType", type).and().isNotNull("json");
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
return careportalEvents;
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public List<CareportalEvent> getCareportalEvents(boolean ascending) {
try {
List<CareportalEvent> careportalEvents;
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.isNotNull("json").and().isNotNull("eventType");
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
return careportalEvents;
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public void deleteCareportalEventById(String _id) {
try {
QueryBuilder<CareportalEvent, Long> queryBuilder;
queryBuilder = getDaoCareportalEvents().queryBuilder();
Where where = queryBuilder.where();
where.eq("_id", _id);
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
List<CareportalEvent> list = getDaoCareportalEvents().query(preparedQuery);
if (list.size() == 1) {
CareportalEvent record = list.get(0);
aapsLogger.debug(LTag.DATABASE, "Removing CareportalEvent record from database: " + record.toString());
delete(record);
} else {
aapsLogger.debug(LTag.DATABASE, "CareportalEvent not found database: " + _id);
}
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
}
public void createCareportalEventFromJsonIfNotExists(JSONObject trJson) {
try {
QueryBuilder<CareportalEvent, Long> queryBuilder;
queryBuilder = getDaoCareportalEvents().queryBuilder();
Where where = queryBuilder.where();
where.eq("_id", trJson.getString("_id")).or().eq("date", trJson.getLong("mills"));
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
List<CareportalEvent> list = getDaoCareportalEvents().query(preparedQuery);
CareportalEvent careportalEvent;
if (list.size() == 0) {
careportalEvent = new CareportalEvent(StaticInjector.Companion.getInstance());
careportalEvent.source = Source.NIGHTSCOUT;
aapsLogger.debug(LTag.DATABASE, "Adding CareportalEvent record to database: " + trJson.toString());
// Record does not exists. add
} else if (list.size() == 1) {
careportalEvent = list.get(0);
aapsLogger.debug(LTag.DATABASE, "Updating CareportalEvent record in database: " + trJson.toString());
} else {
aapsLogger.error("Something went wrong");
return;
}
careportalEvent.date = trJson.getLong("mills");
careportalEvent.eventType = trJson.getString("eventType");
careportalEvent.json = trJson.toString();
careportalEvent._id = trJson.getString("_id");
createOrUpdate(careportalEvent);
} catch (SQLException | JSONException e) {
aapsLogger.error("Unhandled exception: " + trJson.toString(), e);
}
}
private void scheduleCareportalEventChange() {
class PostRunnable implements Runnable {
public void run() {
aapsLogger.debug(LTag.DATABASE, "Firing scheduleCareportalEventChange");
rxBus.send(new EventCareportalEventChange());
scheduledCareportalEventPost = null;
}
}
// prepare task for execution in 1 sec
// cancel waiting task to prevent sending multiple posts
if (scheduledCareportalEventPost != null)
scheduledCareportalEventPost.cancel(false);
Runnable task = new PostRunnable();
final int sec = 1;
scheduledCareportalEventPost = careportalEventWorker.schedule(task, sec, TimeUnit.SECONDS);
}
// ---------------- ProfileSwitch handling ---------------
public List<ProfileSwitch> getProfileSwitchData(long from, boolean ascending) {
@ -1726,9 +1494,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public long getCountOfAllRows() {
try {
return getDaoCareportalEvents().countOf()
+ getDaoExtendedBolus().countOf()
+ getDaoCareportalEvents().countOf()
return getDaoExtendedBolus().countOf()
+ getDaoProfileSwitch().countOf()
+ getDaoTDD().countOf()
+ getDaoTemporaryBasal().countOf();

View file

@ -24,10 +24,6 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
@Inject DatabaseHelperProvider() {
}
@Override public void createOrUpdate(@NonNull CareportalEvent careportalEvent) {
MainApp.Companion.getDbHelper().createOrUpdate(careportalEvent);
}
@Override public void createOrUpdate(@NonNull DanaRHistoryRecord record) {
MainApp.Companion.getDbHelper().createOrUpdate(record);
}
@ -92,10 +88,6 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
return MainApp.Companion.getDbHelper().getTemporaryBasalsDataFromTime(mills, ascending);
}
@Override public CareportalEvent getCareportalEventFromTimestamp(long timestamp) {
return MainApp.Companion.getDbHelper().getCareportalEventFromTimestamp(timestamp);
}
@NonNull @Override public List<OmnipodHistoryRecord> getAllOmnipodHistoryRecordsFromTimestamp(long timestamp, boolean ascending) {
return MainApp.Companion.getDbHelper().getAllOmnipodHistoryRecordsFromTimeStamp(timestamp, ascending);
}
@ -168,10 +160,6 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
MainApp.Companion.getDbHelper().deleteExtendedBolusById(_id);
}
@Override public void deleteCareportalEventById(@NonNull String _id) {
MainApp.Companion.getDbHelper().deleteCareportalEventById(_id);
}
@Override public void deleteProfileSwitchById(@NonNull String _id) {
MainApp.Companion.getDbHelper().deleteProfileSwitchById(_id);
}
@ -184,10 +172,6 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
MainApp.Companion.getDbHelper().createExtendedBolusFromJsonIfNotExists(json);
}
@Override public void createCareportalEventFromJsonIfNotExists(@NonNull JSONObject json) {
MainApp.Companion.getDbHelper().createCareportalEventFromJsonIfNotExists(json);
}
@Override public void createProfileSwitchFromJsonIfNotExists(@NonNull ActivePluginProvider activePluginProvider, @NonNull NSUpload nsUpload, @NonNull JSONObject trJson) {
MainApp.Companion.getDbHelper().createProfileSwitchFromJsonIfNotExists(activePluginProvider, nsUpload, trJson);
}
@ -200,34 +184,10 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
MainApp.Companion.getDbHelper().createOrUpdate(record);
}
@Override public void delete(@NonNull CareportalEvent careportalEvent) {
MainApp.Companion.getDbHelper().delete(careportalEvent);
}
@Override public void delete(@NonNull ProfileSwitch profileSwitch) {
MainApp.Companion.getDbHelper().delete(profileSwitch);
}
@Nullable @Override public CareportalEvent getLastCareportalEvent(@NonNull String event) {
return MainApp.Companion.getDbHelper().getLastCareportalEvent(event);
}
@NonNull @Override public List<CareportalEvent> getCareportalEventsFromTime(long mills, boolean ascending) {
return MainApp.Companion.getDbHelper().getCareportalEventsFromTime(mills, ascending);
}
@NonNull @Override public List<CareportalEvent> getCareportalEventsFromTime(long mills, @NonNull String type, boolean ascending) {
return MainApp.Companion.getDbHelper().getCareportalEventsFromTime(mills, type, ascending);
}
@NonNull @Override public List<CareportalEvent> getCareportalEvents(long start, long end, boolean ascending) {
return MainApp.Companion.getDbHelper().getCareportalEvents(start, end, ascending);
}
@NonNull @Override public List<CareportalEvent> getCareportalEvents(boolean ascending) {
return MainApp.Companion.getDbHelper().getCareportalEvents(ascending);
}
@NonNull @Override public List<ProfileSwitch> getProfileSwitchEventsFromTime(long from, long to, boolean ascending) {
return MainApp.Companion.getDbHelper().getProfileSwitchEventsFromTime(from, to, ascending);
}
@ -236,10 +196,6 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
return MainApp.Companion.getDbHelper().getProfileSwitchEventsFromTime(mills, ascending);
}
@NonNull @Override public List<CareportalEvent> getAllCareportalEvents() {
return MainApp.Companion.getDbHelper().getAllCareportalEvents();
}
@NonNull @Override public List<ExtendedBolus> getAllExtendedBoluses() {
return MainApp.Companion.getDbHelper().getAllExtendedBoluses();
}
@ -260,10 +216,6 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
return MainApp.Companion.getDbHelper().getAllOHQueueItems(maxEntries);
}
@Override public void resetCareportalEvents() {
MainApp.Companion.getDbHelper().resetCareportalEvents();
}
@Override public void resetProfileSwitch() {
MainApp.Companion.getDbHelper().resetProfileSwitch();
}

View file

@ -14,6 +14,7 @@ import info.nightscout.androidaps.databinding.DialogCalibrationBinding
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.XdripCalibrations
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
@ -29,6 +30,7 @@ class CalibrationDialog : DialogFragmentWithDate() {
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var xdripCalibrations: XdripCalibrations
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
private var _binding: DialogCalibrationBinding? = null
@ -52,7 +54,7 @@ class CalibrationDialog : DialogFragmentWithDate() {
super.onViewCreated(view, savedInstanceState)
val units = profileFunction.getUnits()
val bg = Profile.fromMgdlToUnits(GlucoseStatus(injector).glucoseStatusData?.glucose
val bg = Profile.fromMgdlToUnits(glucoseStatusProvider.glucoseStatusData?.glucose
?: 0.0, units)
if (units == Constants.MMOL)
binding.bg.setParams(savedInstanceState?.getDouble("bg")

View file

@ -13,10 +13,10 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.entities.UserEntry.*
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
import info.nightscout.androidaps.databinding.DialogCarbsBinding
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.LTag
@ -275,11 +275,11 @@ class CarbsDialog : DialogFragmentWithDate() {
uel.log(Action.CARBS, notes, ValueWithUnit(eventTime, Units.Timestamp), ValueWithUnit(carbsAfterConstraints, Units.G), ValueWithUnit(timeOffset, Units.M))
else
uel.log(Action.CARBS, notes, ValueWithUnit(carbsAfterConstraints, Units.G), ValueWithUnit(timeOffset, Units.M))
carbsGenerator.createCarb(carbsAfterConstraints, time, CareportalEvent.CARBCORRECTION, notes)
carbsGenerator.createCarb(carbsAfterConstraints, time, TherapyEvent.Type.CARBS_CORRECTION.text, notes)
} else {
uel.log(Action.CARBS, notes, ValueWithUnit(carbsAfterConstraints, Units.G), ValueWithUnit(timeOffset,Units.M), ValueWithUnit(duration, Units.H))
carbsGenerator.generateCarbs(carbsAfterConstraints, time, duration, notes)
nsUpload.uploadEvent(CareportalEvent.NOTE, DateUtil.now() - 2000, resourceHelper.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset))
nsUpload.uploadEvent(TherapyEvent.Type.NOTE.text, DateUtil.now() - 2000, resourceHelper.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset))
}
}
if (useAlarm && carbs > 0 && timeOffset > 0) {

View file

@ -13,21 +13,23 @@ import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.transactions.InsertTherapyEventIfNewTransaction
import info.nightscout.androidaps.database.entities.UserEntry.*
import info.nightscout.androidaps.databinding.DialogCareBinding
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.Translator
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.json.JSONObject
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import java.text.DecimalFormat
import java.util.*
import javax.inject.Inject
@ -41,7 +43,10 @@ class CareDialog : DialogFragmentWithDate() {
@Inject lateinit var nsUpload: NSUpload
@Inject lateinit var translator: Translator
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var repository: AppRepository
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
private val disposable = CompositeDisposable()
enum class EventType {
BGCHECK,
@ -116,7 +121,7 @@ class CareDialog : DialogFragmentWithDate() {
when (options) {
EventType.QUESTION,
EventType.ANNOUNCEMENT,
EventType.BGCHECK -> {
EventType.BGCHECK -> {
binding.durationLayout.visibility = View.GONE
}
@ -128,13 +133,13 @@ class CareDialog : DialogFragmentWithDate() {
}
EventType.NOTE,
EventType.EXERCISE -> {
EventType.EXERCISE -> {
binding.bgLayout.visibility = View.GONE
binding.bgsource.visibility = View.GONE
}
}
val bg = Profile.fromMgdlToUnits(GlucoseStatus(injector).glucoseStatusData?.glucose
val bg = Profile.fromMgdlToUnits(glucoseStatusProvider.glucoseStatusData?.glucose
?: 0.0, profileFunction.getUnits())
val bgTextWatcher: TextWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable) {}
@ -165,76 +170,67 @@ class CareDialog : DialogFragmentWithDate() {
}
override fun submit(): Boolean {
val enteredBy = sp.getString("careportal_enteredby", "")
val enteredBy = sp.getString("careportal_enteredby", "AndroidAPS")
val unitResId = if (profileFunction.getUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol
val json = JSONObject()
eventTime -= eventTime % 1000
val therapyEvent = TherapyEvent(
timestamp = eventTime,
type = when (options) {
EventType.BGCHECK -> TherapyEvent.Type.FINGER_STICK_BG_VALUE
EventType.SENSOR_INSERT -> TherapyEvent.Type.SENSOR_CHANGE
EventType.BATTERY_CHANGE -> TherapyEvent.Type.PUMP_BATTERY_CHANGE
EventType.NOTE -> TherapyEvent.Type.NOTE
EventType.EXERCISE -> TherapyEvent.Type.EXERCISE
EventType.QUESTION -> TherapyEvent.Type.QUESTION
EventType.ANNOUNCEMENT -> TherapyEvent.Type.ANNOUNCEMENT
},
units = profileFunction.getUnits()
)
val actions: LinkedList<String> = LinkedList()
if (options == EventType.BGCHECK || options == EventType.QUESTION || options == EventType.ANNOUNCEMENT) {
val type =
val meterType =
when {
binding.meter.isChecked -> CareportalEvent.FINGER
binding.sensor.isChecked -> CareportalEvent.SENSOR
else -> CareportalEvent.MANUAL
binding.meter.isChecked -> TherapyEvent.MeterType.FINGER
binding.sensor.isChecked -> TherapyEvent.MeterType.SENSOR
else -> TherapyEvent.MeterType.MANUAL
}
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_glucosetype) + ": " + translator.translate(type))
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_glucosetype) + ": " + translator.translate(meterType.text))
actions.add(resourceHelper.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, binding.bg.value) + " " + resourceHelper.gs(unitResId))
therapyEvent.glucoseType = meterType
therapyEvent.glucose = binding.bg.value
valuesWithUnit.add(ValueWithUnit(binding.bg.value.toDouble(), profileFunction.getUnits()))
valuesWithUnit.add(ValueWithUnit(type, Units.CPEvent))
json.put("glucose", binding.bg.value)
json.put("glucoseType", type)
valuesWithUnit.add(ValueWithUnit(meterType, Units.CPEvent))
}
if (options == EventType.NOTE || options == EventType.EXERCISE) {
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_duration_label) + ": " + resourceHelper.gs(R.string.format_mins, binding.duration.value.toInt()))
therapyEvent.duration = T.mins(binding.duration.value.toLong()).msecs()
if (!binding.duration.value.equals(0.0)) valuesWithUnit.add(ValueWithUnit(binding.duration.value.toInt(), Units.M))
json.put("duration", binding.duration.value.toInt())
}
val notes = binding.notesLayout.notes.text.toString()
if (notes.isNotEmpty()) {
actions.add(resourceHelper.gs(R.string.notes_label) + ": " + notes)
json.put("notes", notes)
therapyEvent.note = notes
}
eventTime -= eventTime % 1000
if (eventTimeChanged) {
actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
valuesWithUnit.add(0, ValueWithUnit(eventTime, Units.Timestamp))
}
json.put("created_at", DateUtil.toISOString(eventTime))
json.put("mills", eventTime)
json.put("eventType", when (options) {
EventType.BGCHECK -> CareportalEvent.BGCHECK
EventType.SENSOR_INSERT -> CareportalEvent.SENSORCHANGE
EventType.BATTERY_CHANGE -> CareportalEvent.PUMPBATTERYCHANGE
EventType.NOTE -> CareportalEvent.NOTE
EventType.EXERCISE -> CareportalEvent.EXERCISE
EventType.QUESTION -> CareportalEvent.QUESTION
EventType.ANNOUNCEMENT -> CareportalEvent.ANNOUNCEMENT
})
json.put("units", profileFunction.getUnits())
if (enteredBy.isNotEmpty())
json.put("enteredBy", enteredBy)
therapyEvent.enteredBy = enteredBy
activity?.let { activity ->
OKDialog.showConfirmation(activity, resourceHelper.gs(event), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
val careportalEvent = CareportalEvent(injector)
careportalEvent.date = eventTime
careportalEvent.source = Source.USER
careportalEvent.eventType = when (options) {
EventType.BGCHECK -> CareportalEvent.BGCHECK
EventType.SENSOR_INSERT -> CareportalEvent.SENSORCHANGE
EventType.BATTERY_CHANGE -> CareportalEvent.PUMPBATTERYCHANGE
EventType.NOTE -> CareportalEvent.NOTE
EventType.EXERCISE -> CareportalEvent.EXERCISE
EventType.QUESTION -> CareportalEvent.QUESTION
EventType.ANNOUNCEMENT -> CareportalEvent.ANNOUNCEMENT
}
valuesWithUnit.add(if (eventTimeChanged) 1 else 0, ValueWithUnit(careportalEvent.eventType, Units.CPEvent))
careportalEvent.json = json.toString()
disposable += repository.runTransactionForResult(InsertTherapyEventIfNewTransaction(therapyEvent)).subscribe({ result ->
result.inserted.forEach { nsUpload.uploadEvent(it) }
}, {
aapsLogger.error(LTag.BGSOURCE, "Error while saving therapy event", it)
})
valuesWithUnit.add(if (eventTimeChanged) 1 else 0, ValueWithUnit(therapyEvent.type.text, Units.CPEvent))
uel.log(Action.CAREPORTAL, notes, valuesWithUnit)
databaseHelper.createOrUpdate(careportalEvent)
nsUpload.uploadCareportalEntryToNS(json, eventTime)
}, null)
}
return true

View file

@ -9,13 +9,16 @@ import com.google.common.base.Joiner
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.transactions.InsertTherapyEventIfNewTransaction
import info.nightscout.androidaps.database.entities.UserEntry.*
import info.nightscout.androidaps.databinding.DialogFillBinding
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
@ -26,6 +29,8 @@ import info.nightscout.androidaps.utils.SafeParse
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.extensions.formatColor
import info.nightscout.androidaps.utils.resources.ResourceHelper
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import java.util.*
import javax.inject.Inject
import kotlin.math.abs
@ -39,6 +44,9 @@ class FillDialog : DialogFragmentWithDate() {
@Inject lateinit var commandQueue: CommandQueueProvider
@Inject lateinit var activePlugin: ActivePluginProvider
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var repository: AppRepository
private val disposable = CompositeDisposable()
private var _binding: DialogFillBinding? = null
@ -133,12 +141,28 @@ class FillDialog : DialogFragmentWithDate() {
}
if (siteChange) {
uel.log(Action.SITE_CHANGE, notes)
nsUpload.generateCareportalEvent(CareportalEvent.SITECHANGE, eventTime, notes)
disposable += repository.runTransactionForResult(InsertTherapyEventIfNewTransaction(
timestamp = eventTime,
type = TherapyEvent.Type.CANNULA_CHANGE,
note = notes
)).subscribe({ result ->
result.inserted.forEach { nsUpload.uploadEvent(it) }
}, {
aapsLogger.error(LTag.BGSOURCE, "Error while saving therapy event", it)
})
}
if (insulinChange) {
// add a second for case of both checked
uel.log(Action.INSULIN_CHANGE, notes)
nsUpload.generateCareportalEvent(CareportalEvent.INSULINCHANGE, eventTime + 1000, notes)
disposable += repository.runTransactionForResult(InsertTherapyEventIfNewTransaction(
timestamp = eventTime + 1000,
type = TherapyEvent.Type.INSULIN_CHANGE,
note = notes
)).subscribe({ result ->
result.inserted.forEach { nsUpload.uploadEvent(it) }
}, {
aapsLogger.error(LTag.BGSOURCE, "Error while saving therapy event", it)
})
}
}, null)
}

View file

@ -16,10 +16,10 @@ import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.entities.UserEntry.*
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
import info.nightscout.androidaps.databinding.DialogInsulinBinding
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.CommandQueueProvider
@ -205,7 +205,7 @@ class InsulinDialog : DialogFragmentWithDate() {
}
if (insulinAfterConstraints > 0) {
val detailedBolusInfo = DetailedBolusInfo()
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS
detailedBolusInfo.eventType = TherapyEvent.Type.CORRECTION_BOLUS.text
detailedBolusInfo.insulin = insulinAfterConstraints
detailedBolusInfo.context = context
detailedBolusInfo.source = Source.USER

View file

@ -12,9 +12,9 @@ import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.entities.UserEntry.*
import info.nightscout.androidaps.databinding.DialogTreatmentBinding
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.CommandQueueProvider
@ -132,8 +132,8 @@ class TreatmentDialog : DialogFragmentWithDate() {
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.overview_treatment_label), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
uel.log(Action.TREATMENT, ValueWithUnit(insulin, Units.U), ValueWithUnit(carbs, Units.G))
val detailedBolusInfo = DetailedBolusInfo()
if (insulinAfterConstraints == 0.0) detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION
if (carbsAfterConstraints == 0) detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS
if (insulinAfterConstraints == 0.0) detailedBolusInfo.eventType = TherapyEvent.Type.CARBS_CORRECTION.text
if (carbsAfterConstraints == 0) detailedBolusInfo.eventType = TherapyEvent.Type.CORRECTION_BOLUS.text
detailedBolusInfo.insulin = insulinAfterConstraints
detailedBolusInfo.carbs = carbsAfterConstraints.toDouble()
detailedBolusInfo.context = context

View file

@ -1,3 +1,3 @@
package info.nightscout.androidaps.events
class EventCareportalEventChange : Event()
class EventTherapyEventChange : Event()

View file

@ -15,7 +15,9 @@ import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.transactions.InsertTherapyEventIfNewTransaction
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.events.EventAcceptOpenLoopChange
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
@ -50,8 +52,7 @@ 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 org.json.JSONException
import org.json.JSONObject
import io.reactivex.rxkotlin.plusAssign
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.abs
@ -76,7 +77,8 @@ open class LoopPlugin @Inject constructor(
private val receiverStatusStore: ReceiverStatusStore,
private val fabricPrivacy: FabricPrivacy,
private val nsUpload: NSUpload,
private val databaseHelper: DatabaseHelperInterface
private val dateUtil: DateUtil,
private val repository: AppRepository
) : PluginBase(PluginDescription()
.mainType(PluginType.LOOP)
.fragmentClass(LoopFragment::class.java.name)
@ -594,7 +596,7 @@ open class LoopPlugin @Inject constructor(
// deliver SMB
val detailedBolusInfo = DetailedBolusInfo()
detailedBolusInfo.lastKnownBolusTime = treatmentsPlugin.lastBolusTime
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS
detailedBolusInfo.eventType = TherapyEvent.Type.CORRECTION_BOLUS.text
detailedBolusInfo.insulin = request.smb
detailedBolusInfo.isSMB = true
detailedBolusInfo.source = Source.USER
@ -652,20 +654,16 @@ open class LoopPlugin @Inject constructor(
}
override fun createOfflineEvent(durationInMinutes: Int) {
val data = JSONObject()
try {
data.put("eventType", CareportalEvent.OPENAPSOFFLINE)
data.put("duration", durationInMinutes)
} catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e)
}
val event = CareportalEvent(injector)
event.date = DateUtil.now()
event.source = Source.USER
event.eventType = CareportalEvent.OPENAPSOFFLINE
event.json = data.toString()
databaseHelper.createOrUpdate(event)
nsUpload.uploadOpenAPSOffline(event)
disposable += repository.runTransactionForResult(InsertTherapyEventIfNewTransaction(
timestamp = dateUtil._now(),
type = TherapyEvent.Type.APS_OFFLINE,
duration = T.mins(durationInMinutes.toLong()).msecs(),
enteredBy = "openaps://" + "AndroidAPS"
)).subscribe({ result ->
result.inserted.forEach { nsUpload.uploadEvent(it) }
}, {
aapsLogger.error(LTag.BGSOURCE, "Error while saving therapy event", it)
})
}
companion object {

View file

@ -16,6 +16,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
@ -44,7 +45,8 @@ open class OpenAPSAMAPlugin @Inject constructor(
private val profiler: Profiler,
private val fabricPrivacy: FabricPrivacy,
private val dateUtil: DateUtil,
private val repository: AppRepository
private val repository: AppRepository,
private val glucoseStatusProvider: GlucoseStatusProvider
) : PluginBase(PluginDescription()
.mainType(PluginType.APS)
.fragmentClass(OpenAPSAMAFragment::class.java.name)
@ -81,7 +83,7 @@ open class OpenAPSAMAPlugin @Inject constructor(
aapsLogger.debug(LTag.APS, "invoke from $initiator tempBasalFallback: $tempBasalFallback")
lastAPSResult = null
val determineBasalAdapterAMAJS = DetermineBasalAdapterAMAJS(ScriptReader(context), injector)
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
val profile = profileFunction.getProfile()
val pump = activePlugin.activePump
if (profile == null) {

View file

@ -18,6 +18,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HardLimits
@ -45,7 +46,8 @@ open class OpenAPSSMBPlugin @Inject constructor(
private val profiler: Profiler,
private val sp: SP,
private val dateUtil: DateUtil,
private val repository: AppRepository
private val repository: AppRepository,
private val glucoseStatusProvider: GlucoseStatusProvider
) : PluginBase(PluginDescription()
.mainType(PluginType.APS)
.fragmentClass(OpenAPSSMBFragment::class.java.name)
@ -89,7 +91,7 @@ open class OpenAPSSMBPlugin @Inject constructor(
override fun invoke(initiator: String, tempBasalFallback: Boolean) {
aapsLogger.debug(LTag.APS, "invoke from $initiator tempBasalFallback: $tempBasalFallback")
lastAPSResult = null
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
val profile = profileFunction.getProfile()
val pump = activePlugin.activePump
if (profile == null) {

View file

@ -236,7 +236,7 @@ class ActionsFragment : DaggerFragment() {
.observeOn(aapsSchedulers.main)
.subscribe({ updateGui() }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventCareportalEventChange::class.java)
.toObservable(EventTherapyEventChange::class.java)
.observeOn(aapsSchedulers.main)
.subscribe({ updateGui() }, fabricPrivacy::logException)
updateGui()

View file

@ -8,12 +8,12 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.events.EventExtendedBolusChange
import info.nightscout.androidaps.events.EventNewBasalProfile
import info.nightscout.androidaps.events.EventTempBasalChange
import info.nightscout.androidaps.events.EventTreatmentChange
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.events.*
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui
@ -21,9 +21,8 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.services.Intents
import info.nightscout.androidaps.utils.DefaultValueHelper
@ -51,7 +50,7 @@ class DataBroadcastPlugin @Inject constructor(
private val activePlugin: ActivePluginProvider,
private var receiverStatusStore: ReceiverStatusStore,
private val config: Config,
private val databaseHelper: DatabaseHelperInterface
private val glucoseStatusProvider: GlucoseStatusProvider
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
@ -123,14 +122,14 @@ class DataBroadcastPlugin @Inject constructor(
private fun bgStatus(bundle: Bundle) {
val lastBG = iobCobCalculatorPlugin.lastBg() ?: return
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData ?: return
val glucoseStatus = glucoseStatusProvider.glucoseStatusData ?: return
bundle.putDouble("glucoseMgdl", lastBG.value) // last BG in mgdl
bundle.putLong("glucoseTimeStamp", lastBG.timestamp) // timestamp
bundle.putString("units", profileFunction.getUnits()) // units used in AAPS "mg/dl" or "mmol"
bundle.putString("slopeArrow", lastBG.trendArrow.text) // direction arrow as string
bundle.putDouble("deltaMgdl", glucoseStatus.delta) // bg delta in mgdl
bundle.putDouble("avgDeltaMgdl", glucoseStatus.avgDelta) // average bg delta
bundle.putDouble("avgDeltaMgdl", glucoseStatus.shortAvgDelta) // average bg delta
bundle.putDouble("high", defaultValueHelper.determineHighLine()) // predefined top value of in range (green area)
bundle.putDouble("low", defaultValueHelper.determineLowLine()) // predefined bottom value of in range
}

View file

@ -30,9 +30,10 @@ import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.database.AppRepository;
import info.nightscout.androidaps.database.entities.TemporaryTarget;
import info.nightscout.androidaps.database.entities.TherapyEvent;
import info.nightscout.androidaps.database.entities.UserEntry.*;
import info.nightscout.androidaps.database.transactions.SyncTemporaryTargetTransaction;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.database.transactions.SyncTherapyEventTransaction;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventChargingState;
import info.nightscout.androidaps.events.EventNetworkChange;
@ -70,6 +71,9 @@ import io.reactivex.disposables.CompositeDisposable;
import static info.nightscout.androidaps.utils.extensions.TemporaryTargetExtensionKt.temporaryTargetFromJson;
import static info.nightscout.androidaps.utils.extensions.TemporaryTargetExtensionKt.temporaryTargetFromNsIdForInvalidating;
import static info.nightscout.androidaps.utils.extensions.TherapyEventExtensionKt.therapyEventFromJson;
import static info.nightscout.androidaps.utils.extensions.TherapyEventExtensionKt.therapyEventFromNsIdForInvalidating;
import static info.nightscout.androidaps.utils.extensions.TherapyEventExtensionKt.therapyEventFromNsMbg;
@Singleton
public class NSClientPlugin extends PluginBase {
@ -425,14 +429,18 @@ public class NSClientPlugin extends PluginBase {
TemporaryTarget temporaryTarget = temporaryTargetFromNsIdForInvalidating(_id);
disposable.add(repository.runTransactionForResult(new SyncTemporaryTargetTransaction(temporaryTarget)).subscribe(
result -> result.getInvalidated().forEach(record -> uel.log(Action.TT_DELETED_FROM_NS, new ValueWithUnit(record.getReason().getText(), Units.TT_Reason), new ValueWithUnit(record.getLowTarget(), Units.Mg_Dl), new ValueWithUnit(record.getHighTarget(), Units.Mg_Dl), new ValueWithUnit((int) record.getDuration()/60000, Units.M))),
error -> aapsLogger.error(LTag.BGSOURCE, "Error while saving temporary target", error)));
error -> aapsLogger.error(LTag.DATABASE, "Error while removing temporary target", error)));
// room Therapy Event
TherapyEvent therapyEvent = therapyEventFromNsIdForInvalidating(_id);
disposable.add(repository.runTransactionForResult(new SyncTherapyEventTransaction(therapyEvent)).subscribe(
result -> result.getInvalidated().forEach(record -> uel.log("CAREPORTAL EVENT DELETED FROM NS", record.getType().getText(), 0.0, 0.0, 0, 0)),
error -> aapsLogger.error(LTag.DATABASE, "Error while removing therapy event", error)));
// new DB model
EventNsTreatment evtTreatment = new EventNsTreatment(EventNsTreatment.Companion.getREMOVE(), json);
rxBus.send(evtTreatment);
// old DB model
databaseHelper.deleteTempBasalById(_id);
databaseHelper.deleteExtendedBolusById(_id);
databaseHelper.deleteCareportalEventById(_id);
databaseHelper.deleteProfileSwitchById(_id);
}
@ -449,40 +457,52 @@ public class NSClientPlugin extends PluginBase {
if (insulin > 0 || carbs > 0) {
EventNsTreatment evtTreatment = new EventNsTreatment(mode, json);
rxBus.send(evtTreatment);
} else if (eventType.equals(CareportalEvent.TEMPORARYTARGET)) {
} else if (eventType.equals(TherapyEvent.Type.TEMPORARY_TARGET.getText())) {
TemporaryTarget temporaryTarget = temporaryTargetFromJson(json);
if (temporaryTarget != null) {
disposable.add(repository.runTransactionForResult(new SyncTemporaryTargetTransaction(temporaryTarget)).subscribe(
result -> {
result.getInserted().forEach(record -> uel.log(Action.TT_FROM_NS, new ValueWithUnit(record.getReason().getText(), Units.TT_Reason), new ValueWithUnit(record.getLowTarget(), Units.Mg_Dl), new ValueWithUnit(record.getHighTarget(), Units.Mg_Dl), new ValueWithUnit((int) record.getDuration()/60000, Units.M)));
result.getInvalidated().forEach(record -> uel.log(Action.TT_DELETED_FROM_NS, new ValueWithUnit(record.getReason().getText(), Units.TT_Reason), new ValueWithUnit(record.getLowTarget(), Units.Mg_Dl), new ValueWithUnit(record.getHighTarget(), Units.Mg_Dl), new ValueWithUnit((int) record.getDuration()/60000, Units.M)));
result.getEnded().forEach(record -> uel.log(Action.TT_CANCELED_FROM_NS, new ValueWithUnit(record.getReason().getText(), Units.TT_Reason), new ValueWithUnit(record.getLowTarget(), Units.Mg_Dl), new ValueWithUnit(record.getHighTarget(), Units.Mg_Dl), new ValueWithUnit((int) record.getDuration()/60000, Units.M)));
},
error -> aapsLogger.error(LTag.BGSOURCE, "Error while saving temporary target", error)));
disposable.add(repository.runTransactionForResult(new SyncTemporaryTargetTransaction(temporaryTarget))
.subscribe(
result -> {
result.getInserted().forEach(record -> uel.log(Action.TT_FROM_NS, new ValueWithUnit(record.getReason().getText(), Units.TT_Reason), new ValueWithUnit(record.getLowTarget(), Units.Mg_Dl), new ValueWithUnit(record.getHighTarget(), Units.Mg_Dl), new ValueWithUnit((int) record.getDuration()/60000, Units.M)));
result.getInvalidated().forEach(record -> uel.log(Action.TT_DELETED_FROM_NS, new ValueWithUnit(record.getReason().getText(), Units.TT_Reason), new ValueWithUnit(record.getLowTarget(), Units.Mg_Dl), new ValueWithUnit(record.getHighTarget(), Units.Mg_Dl), new ValueWithUnit((int) record.getDuration()/60000, Units.M)));
result.getEnded().forEach(record -> uel.log(Action.TT_CANCELED_FROM_NS, new ValueWithUnit(record.getReason().getText(), Units.TT_Reason), new ValueWithUnit(record.getLowTarget(), Units.Mg_Dl), new ValueWithUnit(record.getHighTarget(), Units.Mg_Dl), new ValueWithUnit((int) record.getDuration()/60000, Units.M)));
},
error -> aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", error)));
} else {
aapsLogger.error("Error parsing TT json " + json.toString());
}
} else if (eventType.equals(CareportalEvent.TEMPBASAL)) {
} else if (eventType.equals(TherapyEvent.Type.TEMPORARY_BASAL.getText())) {
databaseHelper.createTempBasalFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.COMBOBOLUS)) {
} else if (eventType.equals(TherapyEvent.Type.COMBO_BOLUS.getText())) {
databaseHelper.createExtendedBolusFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.PROFILESWITCH)) {
} else if (eventType.equals(TherapyEvent.Type.PROFILE_SWITCH.getText())) {
databaseHelper.createProfileSwitchFromJsonIfNotExists(activePlugin, nsUpload, json);
} else if (eventType.equals(CareportalEvent.SITECHANGE) ||
eventType.equals(CareportalEvent.INSULINCHANGE) ||
eventType.equals(CareportalEvent.SENSORCHANGE) ||
eventType.equals(CareportalEvent.BGCHECK) ||
eventType.equals(CareportalEvent.NOTE) ||
eventType.equals(CareportalEvent.NONE) ||
eventType.equals(CareportalEvent.ANNOUNCEMENT) ||
eventType.equals(CareportalEvent.QUESTION) ||
eventType.equals(CareportalEvent.EXERCISE) ||
eventType.equals(CareportalEvent.OPENAPSOFFLINE) ||
eventType.equals(CareportalEvent.PUMPBATTERYCHANGE)) {
databaseHelper.createCareportalEventFromJsonIfNotExists(json);
} else if (eventType.equals(TherapyEvent.Type.CANNULA_CHANGE.getText()) ||
eventType.equals(TherapyEvent.Type.INSULIN_CHANGE.getText()) ||
eventType.equals(TherapyEvent.Type.SENSOR_CHANGE.getText()) ||
eventType.equals(TherapyEvent.Type.FINGER_STICK_BG_VALUE.getText()) ||
eventType.equals(TherapyEvent.Type.NOTE.getText()) ||
eventType.equals(TherapyEvent.Type.NONE.getText()) ||
eventType.equals(TherapyEvent.Type.ANNOUNCEMENT.getText()) ||
eventType.equals(TherapyEvent.Type.QUESTION.getText()) ||
eventType.equals(TherapyEvent.Type.EXERCISE.getText()) ||
eventType.equals(TherapyEvent.Type.APS_OFFLINE.getText()) ||
eventType.equals(TherapyEvent.Type.PUMP_BATTERY_CHANGE.getText())) {
TherapyEvent therapyEvent = therapyEventFromJson(json);
if (therapyEvent != null) {
disposable.add(repository.runTransactionForResult(new SyncTherapyEventTransaction(therapyEvent))
.subscribe(
result -> {
result.getInserted().forEach(record -> uel.log("CAREPORTAL EVENT NS", record.getType().getText(), 0.0, 0.0, 0, 0));
result.getInvalidated().forEach(record -> uel.log("CAREPORTAL EVENT DELETED FROM NS", record.getType().getText(), 0.0, 0.0, 0, 0));
},
error -> aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", error)));
} else {
aapsLogger.error("Error parsing TherapyEvent json " + json.toString());
}
}
if (eventType.equals(CareportalEvent.ANNOUNCEMENT)) {
if (eventType.equals(TherapyEvent.Type.ANNOUNCEMENT.getText())) {
long date = JsonHelper.safeGetLong(json, "mills");
long now = System.currentTimeMillis();
String enteredBy = JsonHelper.safeGetString(json, "enteredBy", "");
@ -499,9 +519,12 @@ public class NSClientPlugin extends PluginBase {
}
private void storeMbg(JSONObject mbgJson) {
NSMbg nsMbg = new NSMbg(mbgJson);
CareportalEvent careportalEvent = new CareportalEvent(nsMbg);
databaseHelper.createOrUpdate(careportalEvent);
aapsLogger.debug(LTag.DATASERVICE, "Adding/Updating new MBG: " + careportalEvent.toString());
NSMbg nsMbg = new NSMbg(getInjector(), mbgJson);
if (nsMbg.mbg != 0.0 && nsMbg.date != 0)
disposable.add(repository.runTransactionForResult(new SyncTherapyEventTransaction(therapyEventFromNsMbg(nsMbg)))
.subscribe(
result -> aapsLogger.debug(LTag.DATABASE, "Saved therapy event" + result),
error -> aapsLogger.error("Error while saving therapy event", error))
);
}
}

View file

@ -18,6 +18,7 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.db.*
import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
@ -198,23 +199,16 @@ class OpenHumansUploader @Inject constructor(
}
@JvmOverloads
fun enqueueCareportalEvent(careportalEvent: CareportalEvent, deleted: Boolean = false) = insertQueueItem("CareportalEvents") {
put("date", careportalEvent.date)
put("isValid", careportalEvent.isValid)
put("source", careportalEvent.source)
put("nsId", careportalEvent._id)
put("eventType", careportalEvent.eventType)
val data = JSONObject(careportalEvent.json)
val reducedData = JSONObject()
if (data.has("mgdl")) reducedData.put("mgdl", data.getDouble("mgdl"))
if (data.has("glucose")) reducedData.put("glucose", data.getDouble("glucose"))
if (data.has("units")) reducedData.put("units", data.getString("units"))
if (data.has("created_at")) reducedData.put("created_at", data.getString("created_at"))
if (data.has("glucoseType")) reducedData.put("glucoseType", data.getString("glucoseType"))
if (data.has("duration")) reducedData.put("duration", data.getInt("duration"))
if (data.has("mills")) reducedData.put("mills", data.getLong("mills"))
if (data.has("eventType")) reducedData.put("eventType", data.getString("eventType"))
put("data", reducedData)
fun enqueueTherapyEvent(therapyEvent: TherapyEvent, deleted: Boolean = false) = insertQueueItem("TherapyEvents") {
put("date", therapyEvent.timestamp)
put("isValid", therapyEvent.isValid)
put("nsId", therapyEvent.interfaceIDs.nightscoutId)
put("eventType", therapyEvent.type.text)
put("glucose", therapyEvent.glucose)
put("units", therapyEvent.units)
put("glucoseType", therapyEvent.glucoseType?.text)
put("units", therapyEvent.units)
put("duration", therapyEvent.duration)
put("isDeletion", deleted)
}
@ -370,8 +364,8 @@ class OpenHumansUploader @Inject constructor(
.andThen(Observable.defer { Observable.fromIterable(repository.compatGetBgReadingsDataFromTime(0, true).blockingGet()) })
.map { enqueueBGReading(it); increaseCounter() }
.ignoreElements()
.andThen(Observable.defer { Observable.fromIterable(databaseHelper.getAllCareportalEvents()) })
.map { enqueueCareportalEvent(it); increaseCounter() }
.andThen(Observable.defer { Observable.fromIterable(repository.compatGetTherapyEventDataFromTime(0, true).blockingGet()) })
.map { enqueueTherapyEvent(it); increaseCounter() }
.ignoreElements()
.andThen(Observable.defer { Observable.fromIterable(databaseHelper.getAllExtendedBoluses()) })
.map { enqueueExtendedBolus(it); increaseCounter() }

View file

@ -49,7 +49,7 @@ import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizar
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore
import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
@ -118,6 +118,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var repository: AppRepository
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
private val disposable = CompositeDisposable()
@ -246,7 +247,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
.observeOn(aapsSchedulers.io)
.subscribe({ scheduleUpdateGUI("EventAcceptOpenLoopChange") }, fabricPrivacy::logException))
disposable.add(rxBus
.toObservable(EventCareportalEventChange::class.java)
.toObservable(EventTherapyEventChange::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ scheduleUpdateGUI("EventCareportalEventChange") }, fabricPrivacy::logException))
disposable.add(rxBus
@ -299,14 +300,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())
@ -315,7 +316,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)) {
@ -326,7 +327,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)) {
@ -341,7 +342,7 @@ 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
@ -361,7 +362,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
}
}
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) }
@ -393,7 +394,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 ->
@ -403,8 +404,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
@ -591,7 +592,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.infoLayout.arrow.setImageResource(trendCalculator.getTrendArrow(lastBG).directionToIcon())
binding.infoLayout.arrow.setColorFilter(color)
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (glucoseStatus != null) {
binding.infoLayout.deltaLarge.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
binding.infoLayout.deltaLarge.setTextColor(color)

View file

@ -5,14 +5,16 @@ import android.widget.TextView
import androidx.annotation.StringRes
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugin
import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.OmnipodConstants
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.WarnColors
import info.nightscout.androidaps.utils.extensions.age
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
@ -25,7 +27,7 @@ class StatusLightHandler @Inject constructor(
private val activePlugin: ActivePluginProvider,
private val warnColors: WarnColors,
private val config: Config,
private val databaseHelper: DatabaseHelperInterface
private val repository: AppRepository
) {
/**
@ -34,11 +36,11 @@ class StatusLightHandler @Inject constructor(
fun updateStatusLights(careportal_cannula_age: TextView?, careportal_insulin_age: TextView?, careportal_reservoir_level: TextView?, careportal_sensor_age: TextView?, careportal_sensor_battery_level: TextView?, careportal_pb_age: TextView?, careportal_battery_level: TextView?) {
val pump = activePlugin.activePump
val bgSource = activePlugin.activeBgSource
handleAge(careportal_cannula_age, CareportalEvent.SITECHANGE, R.string.key_statuslights_cage_warning, 48.0, R.string.key_statuslights_cage_critical, 72.0)
handleAge(careportal_insulin_age, CareportalEvent.INSULINCHANGE, R.string.key_statuslights_iage_warning, 72.0, R.string.key_statuslights_iage_critical, 144.0)
handleAge(careportal_sensor_age, CareportalEvent.SENSORCHANGE, R.string.key_statuslights_sage_warning, 216.0, R.string.key_statuslights_sage_critical, 240.0)
handleAge(careportal_cannula_age, TherapyEvent.Type.CANNULA_CHANGE, R.string.key_statuslights_cage_warning, 48.0, R.string.key_statuslights_cage_critical, 72.0)
handleAge(careportal_insulin_age, TherapyEvent.Type.INSULIN_CHANGE, R.string.key_statuslights_iage_warning, 72.0, R.string.key_statuslights_iage_critical, 144.0)
handleAge(careportal_sensor_age, TherapyEvent.Type.SENSOR_CHANGE, R.string.key_statuslights_sage_warning, 216.0, R.string.key_statuslights_sage_critical, 240.0)
if (pump.pumpDescription.isBatteryReplaceable || (pump is OmnipodErosPumpPlugin && pump.isUseRileyLinkBatteryLevel && pump.isBatteryChangeLoggingEnabled)) {
handleAge(careportal_pb_age, CareportalEvent.PUMPBATTERYCHANGE, R.string.key_statuslights_bage_warning, 216.0, R.string.key_statuslights_bage_critical, 240.0)
handleAge(careportal_pb_age, TherapyEvent.Type.PUMP_BATTERY_CHANGE, R.string.key_statuslights_bage_warning, 216.0, R.string.key_statuslights_bage_critical, 240.0)
}
if (!config.NSCLIENT) {
if (pump.model() == PumpType.Omnipod_Eros || pump.model() == PumpType.Omnipod_Dash) {
@ -67,13 +69,13 @@ class StatusLightHandler @Inject constructor(
}
}
private fun handleAge(view: TextView?, eventName: String, @StringRes warnSettings: Int, defaultWarnThreshold: Double, @StringRes urgentSettings: Int, defaultUrgentThreshold: Double) {
private fun handleAge(view: TextView?, type: TherapyEvent.Type, @StringRes warnSettings: Int, defaultWarnThreshold: Double, @StringRes urgentSettings: Int, defaultUrgentThreshold: Double) {
val warn = sp.getDouble(warnSettings, defaultWarnThreshold)
val urgent = sp.getDouble(urgentSettings, defaultUrgentThreshold)
val careportalEvent = databaseHelper.getLastCareportalEvent(eventName)
if (careportalEvent != null) {
warnColors.setColorByAge(view, careportalEvent, warn, urgent)
view?.text = careportalEvent.age(resourceHelper.shortTextMode(), resourceHelper)
val therapyEvent = repository.getLastTherapyRecord(type).blockingGet()
if (therapyEvent is ValueWrapper.Existing) {
warnColors.setColorByAge(view, therapyEvent.value, warn, urgent)
view?.text = therapyEvent.value.age(resourceHelper.shortTextMode(), resourceHelper)
} else {
view?.text = if (resourceHelper.shortTextMode()) "-" else resourceHelper.gs(R.string.notavailable)
}

View file

@ -14,6 +14,7 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.GlucoseValueDataPoint
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.TherapyEventDataPoint
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.GlucoseValue
@ -268,10 +269,12 @@ class GraphData(
}
// Careportal
databaseHelper.getCareportalEventsFromTime(fromTime - 6 * 60 * 60 * 1000, true)
// databaseHelper.getCareportalEventsFromTime(fromTime - 6 * 60 * 60 * 1000, true)
repository.compatGetTherapyEventDataFromToTime(fromTime - 6 * 60 * 60 * 1000, endTime).blockingGet()
.map { TherapyEventDataPoint(injector, it) }
.filterTimeframe(fromTime, endTime)
.forEach {
it.y = getNearestBg(it.x.toLong())
if (it.y == 0.0) it.y = getNearestBg(it.x.toLong())
filteredTreatments.add(it)
}

View file

@ -16,6 +16,7 @@ import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.FabricPrivacy
@ -42,7 +43,8 @@ class PersistentNotificationPlugin @Inject constructor(
private val context: Context,
private val notificationHolder: NotificationHolderInterface,
private val dummyServiceHelper: DummyServiceHelper,
private val iconsProvider: IconsProvider
private val iconsProvider: IconsProvider,
private val glucoseStatusProvider: GlucoseStatusProvider
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
.neverVisible(true)
@ -130,13 +132,13 @@ class PersistentNotificationPlugin @Inject constructor(
var line1aa: String
val units = profileFunction.getUnits()
val lastBG = iobCobCalculatorPlugin.lastBg()
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (lastBG != null) {
line1aa = lastBG.valueToUnitsString(units)
line1 = line1aa
if (glucoseStatus != null) {
line1 += (" Δ" + Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
+ " avgΔ" + Profile.toSignedUnitsString(glucoseStatus.avgDelta, glucoseStatus.avgDelta * Constants.MGDL_TO_MMOLL, units))
+ " avgΔ" + Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units))
line1aa += " " + lastBG.trendArrow.symbol
} else {
line1 += " " +

View file

@ -37,6 +37,7 @@ import info.nightscout.androidaps.plugins.general.overview.notifications.Notific
import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.receivers.BundleStore
@ -79,6 +80,7 @@ class SmsCommunicatorPlugin @Inject constructor(
private val dateUtil: DateUtil,
private val uel: UserEntryLogger,
private val nsUpload: NSUpload,
private val glucoseStatusProvider: GlucoseStatusProvider,
private val repository: AppRepository
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
@ -323,7 +325,7 @@ class SmsCommunicatorPlugin @Inject constructor(
val agoMin = (agoMilliseconds / 60.0 / 1000.0).toInt()
reply = resourceHelper.gs(R.string.sms_lastbg) + " " + lastBG.valueToUnitsString(units) + " " + String.format(resourceHelper.gs(R.string.sms_minago), agoMin) + ", "
}
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (glucoseStatus != null) reply += resourceHelper.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", "
activePlugin.activeTreatments.updateTotalIOBTreatments()
val bolusIob = activePlugin.activeTreatments.lastCalculationTreatments.round()

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.general.tidepool.comm
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Intervals
import info.nightscout.androidaps.database.AppRepository
@ -23,10 +22,10 @@ import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.max
import kotlin.math.min
@Singleton
class UploadChunk @Inject constructor(
private val injector: HasAndroidInjector,
private val sp: SP,
private val rxBus: RxBusWrapper,
private val aapsLogger: AAPSLogger,
@ -38,19 +37,19 @@ class UploadChunk @Inject constructor(
private val dateUtil: DateUtil
) {
private val MAX_UPLOAD_SIZE = T.days(7).msecs() // don't change this
private val maxUploadSize = T.days(7).msecs() // don't change this
fun getNext(session: Session?): String? {
if (session == null)
return null
session.start = getLastEnd()
session.end = Math.min(session.start + MAX_UPLOAD_SIZE, DateUtil.now())
session.end = min(session.start + maxUploadSize, DateUtil.now())
val result = get(session.start, session.end)
if (result.length < 3) {
aapsLogger.debug(LTag.TIDEPOOL, "No records in this time period, setting start to best end time")
setLastEnd(Math.max(session.end, getOldestRecordTimeStamp()))
setLastEnd(max(session.end, getOldestRecordTimeStamp()))
}
return result
}
@ -62,7 +61,7 @@ class UploadChunk @Inject constructor(
aapsLogger.debug(LTag.TIDEPOOL, "End is <= start: " + dateUtil.dateAndTimeString(start) + " " + dateUtil.dateAndTimeString(end))
return ""
}
if (end - start > MAX_UPLOAD_SIZE) {
if (end - start > maxUploadSize) {
aapsLogger.debug(LTag.TIDEPOOL, "More than max range - rejecting")
return ""
}
@ -128,7 +127,7 @@ class UploadChunk @Inject constructor(
}
private fun getBloodTests(start: Long, end: Long): List<BloodGlucoseElement> {
val readings = databaseHelper.getCareportalEvents(start, end, true)
val readings = repository.compatGetTherapyEventDataFromToTime(start, end).blockingGet()
val selection = BloodGlucoseElement.fromCareportalEvents(readings)
if (selection.isNotEmpty())
rxBus.send(EventTidepoolStatus("${selection.size} BGs selected for upload"))
@ -148,22 +147,22 @@ class UploadChunk @Inject constructor(
private fun fromTemporaryBasals(tbrList: Intervals<TemporaryBasal>, start: Long, end: Long): List<BasalElement> {
val results = LinkedList<BasalElement>()
for (tbr in tbrList.list) {
if (tbr.date >= start && tbr.date <= end && tbr.durationInMinutes != 0)
if (tbr.date in start..end && tbr.durationInMinutes != 0)
results.add(BasalElement(tbr, profileFunction))
}
return results
}
private fun getBasals(start: Long, end: Long): List<BasalElement> {
val tbrs = treatmentsPlugin.temporaryBasalsFromHistory
tbrs.merge()
val selection = fromTemporaryBasals(tbrs, start, end) // TODO do not upload running TBR
val temporaryBasals = treatmentsPlugin.temporaryBasalsFromHistory
temporaryBasals.merge()
val selection = fromTemporaryBasals(temporaryBasals, start, end) // TODO do not upload running TBR
if (selection.isNotEmpty())
rxBus.send(EventTidepoolStatus("${selection.size} TBRs selected for upload"))
return selection
}
fun newInstanceOrNull(ps: ProfileSwitch): ProfileElement? = try {
private fun newInstanceOrNull(ps: ProfileSwitch): ProfileElement? = try {
ProfileElement(ps, activePlugin.activePump.serialNumber())
} catch (e: Throwable) {
null

View file

@ -1,36 +1,36 @@
package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
import info.nightscout.androidaps.database.entities.TherapyEvent
import java.util.*
class BloodGlucoseElement(careportalEvent: CareportalEvent)
: BaseElement(careportalEvent.date, UUID.nameUUIDFromBytes(("AAPS-bg" + careportalEvent.date).toByteArray()).toString()) {
class BloodGlucoseElement(therapyEvent: TherapyEvent)
: BaseElement(therapyEvent.timestamp, UUID.nameUUIDFromBytes(("AAPS-bg" + therapyEvent.timestamp).toByteArray()).toString()) {
@Expose
var subType: String = "manual"
@Expose
var units: String = "mg/dL"
@Expose
var value: Int = 0
init {
type = "cbg"
subType = "manual" // TODO
val json = if (careportalEvent.json != null) JSONObject(careportalEvent.json) else JSONObject()
value = Profile.toMgdl(JsonHelper.safeGetDouble(json, "glucose"), JsonHelper.safeGetString(json, "units", Constants.MGDL)).toInt()
value = if (therapyEvent.glucose != null && therapyEvent.units != null)
Profile.toMgdl(therapyEvent.glucose!!, therapyEvent.units).toInt()
else 0
}
companion object {
fun fromCareportalEvents(careportalList: List<CareportalEvent>): List<BloodGlucoseElement> {
fun fromCareportalEvents(careportalList: List<TherapyEvent>): List<BloodGlucoseElement> {
val results = LinkedList<BloodGlucoseElement>()
for (bt in careportalList) {
if (bt.eventType == CareportalEvent.MBG || bt.eventType == CareportalEvent.BGCHECK) {
if (bt.type == TherapyEvent.Type.NS_MBG || bt.type == TherapyEvent.Type.FINGER_STICK_BG_VALUE) {
val bge = BloodGlucoseElement(bt)
if (bge.value > 0)
results.add(BloodGlucoseElement(bt))

View file

@ -16,10 +16,10 @@ import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.interfaces.end
import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.db.TDD
import info.nightscout.androidaps.interfaces.*
@ -545,7 +545,7 @@ class ActionStringHandler @Inject constructor(
private fun doECarbs(carbs: Int, time: Long, duration: Int) {
if (carbs > 0) {
if (duration == 0) {
carbsGenerator.createCarb(carbs, time, CareportalEvent.CARBCORRECTION, "watch")
carbsGenerator.createCarb(carbs, time, TherapyEvent.Type.CARBS_CORRECTION.text, "watch")
} else {
carbsGenerator.generateCarbs(carbs, time, duration, "watch eCarbs")
}

View file

@ -51,6 +51,7 @@ import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAction;
import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.receivers.ReceiverStatusStore;
@ -62,7 +63,7 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
public class WatchUpdaterService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
@Inject public HasAndroidInjector injector;
@Inject public GlucoseStatusProvider glucoseStatusProvider;
@Inject public AAPSLogger aapsLogger;
@Inject public WearPlugin wearPlugin;
@Inject public ResourceHelper resourceHelper;
@ -282,7 +283,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
GlucoseValue lastBG = iobCobCalculatorPlugin.lastBg();
// Log.d(TAG, logPrefix + "LastBg=" + lastBG);
if (lastBG != null) {
GlucoseStatus glucoseStatus = new GlucoseStatus(injector).getGlucoseStatusData();
GlucoseStatus glucoseStatus = glucoseStatusProvider.getGlucoseStatusData();
if (googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) {
googleApiConnect();
@ -323,7 +324,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
} else {
dataMap.putString("slopeArrow", slopeArrow(glucoseStatus.getDelta()));
dataMap.putString("delta", deltastring(glucoseStatus.getDelta(), glucoseStatus.getDelta() * Constants.MGDL_TO_MMOLL, units));
dataMap.putString("avgDelta", deltastring(glucoseStatus.getAvgDelta(), glucoseStatus.getAvgDelta() * Constants.MGDL_TO_MMOLL, units));
dataMap.putString("avgDelta", deltastring(glucoseStatus.getShortAvgDelta(), glucoseStatus.getShortAvgDelta() * Constants.MGDL_TO_MMOLL, units));
}
dataMap.putLong("sgvLevel", sgvLevel);
dataMap.putDouble("sgvDouble", lastBG.getValue());
@ -386,7 +387,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
if (last_bg == null) return;
List<GlucoseValue> graph_bgs = repository.compatGetBgReadingsDataFromTime(startTime, true).blockingGet();
GlucoseStatus glucoseStatus = new GlucoseStatus(injector).getGlucoseStatusData(true);
GlucoseStatus glucoseStatus = glucoseStatusProvider.getGlucoseStatusData(true);
if (!graph_bgs.isEmpty()) {
DataMap entries = dataMapSingleBG(last_bg, glucoseStatus);

View file

@ -4,7 +4,8 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.IobCobCalculatorInterface
@ -17,6 +18,7 @@ import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin.Companion.percentile
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.extensions.isEvent5minBack
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONException
@ -34,7 +36,8 @@ open class SensitivityAAPSPlugin @Inject constructor(
sp: SP?,
private val profileFunction: ProfileFunction,
private val dateUtil: DateUtil,
private val databaseHelper: DatabaseHelperInterface
private val databaseHelper: DatabaseHelperInterface,
private val repository: AppRepository
) : AbstractSensitivityPlugin(PluginDescription()
.mainType(PluginType.SENSITIVITY)
.pluginIcon(R.drawable.ic_generic_icon)
@ -67,7 +70,7 @@ open class SensitivityAAPSPlugin @Inject constructor(
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. toTime: " + dateUtil.dateAndTimeString(toTime) + " lastDataTime: " + plugin.lastDataTime())
return AutosensResult()
}
val siteChanges = databaseHelper.getCareportalEventsFromTime(fromTime, CareportalEvent.SITECHANGE, true)
val siteChanges = repository.getTherapyEventDataFromTime(fromTime, TherapyEvent.Type.CANNULA_CHANGE, true).blockingGet()
val profileSwitches = databaseHelper.getProfileSwitchEventsFromTime(fromTime, true)
val deviationsArray: MutableList<Double> = ArrayList()
var pastSensitivity = ""
@ -84,7 +87,7 @@ open class SensitivityAAPSPlugin @Inject constructor(
}
// reset deviations after site change
if (CareportalEvent(injector).isEvent5minBack(siteChanges, autosensData.time)) {
if (isEvent5minBack(siteChanges, autosensData.time)) {
deviationsArray.clear()
pastSensitivity += "(SITECHANGE)"
}

View file

@ -4,7 +4,8 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.IobCobCalculatorInterface
@ -18,6 +19,7 @@ import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin.Companion.percentile
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.extensions.isEvent5minBack
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONException
@ -35,7 +37,8 @@ open class SensitivityOref1Plugin @Inject constructor(
sp: SP?,
private val profileFunction: ProfileFunction,
private val dateUtil: DateUtil,
private val databaseHelper: DatabaseHelperInterface
private val databaseHelper: DatabaseHelperInterface,
private val repository: AppRepository
) : AbstractSensitivityPlugin(PluginDescription()
.mainType(PluginType.SENSITIVITY)
.pluginIcon(R.drawable.ic_generic_icon)
@ -68,7 +71,7 @@ open class SensitivityOref1Plugin @Inject constructor(
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. toTime: " + dateUtil.dateAndTimeString(toTime) + " lastDataTime: " + plugin.lastDataTime())
return AutosensResult()
}
val siteChanges = databaseHelper.getCareportalEventsFromTime(fromTime, CareportalEvent.SITECHANGE, true)
val siteChanges = repository.getTherapyEventDataFromTime(fromTime, TherapyEvent.Type.CANNULA_CHANGE, true).blockingGet()
val profileSwitches = databaseHelper.getProfileSwitchEventsFromTime(fromTime, true)
//[0] = 8 hour
@ -100,7 +103,7 @@ open class SensitivityOref1Plugin @Inject constructor(
var pastSensitivity = pastSensitivityArray[hourSegment]
// reset deviations after site change
if (CareportalEvent(injector).isEvent5minBack(siteChanges, autosensData.time)) {
if (isEvent5minBack(siteChanges, autosensData.time)) {
deviationsArray.clear()
pastSensitivity += "(SITECHANGE)"
}

View file

@ -5,7 +5,8 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.IobCobCalculatorInterface
@ -17,6 +18,7 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.extensions.isEvent5minBack
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONException
@ -33,7 +35,8 @@ open class SensitivityWeightedAveragePlugin @Inject constructor(
sp: SP,
private val profileFunction: ProfileFunction,
private val dateUtil: DateUtil,
private val databaseHelper: DatabaseHelperInterface
private val databaseHelper: DatabaseHelperInterface,
private val repository: AppRepository
) : AbstractSensitivityPlugin(PluginDescription()
.mainType(PluginType.SENSITIVITY)
.pluginIcon(R.drawable.ic_generic_icon)
@ -66,7 +69,7 @@ open class SensitivityWeightedAveragePlugin @Inject constructor(
aapsLogger.debug(LTag.AUTOSENS, "No profile available")
return AutosensResult()
}
val siteChanges = databaseHelper.getCareportalEventsFromTime(fromTime, CareportalEvent.SITECHANGE, true)
val siteChanges = repository.getTherapyEventDataFromTime(fromTime, TherapyEvent.Type.CANNULA_CHANGE, true).blockingGet()
val profileSwitches = databaseHelper.getProfileSwitchEventsFromTime(fromTime, true)
var pastSensitivity = ""
var index = 0
@ -87,7 +90,7 @@ open class SensitivityWeightedAveragePlugin @Inject constructor(
}
// reset deviations after site change
if (CareportalEvent(injector).isEvent5minBack(siteChanges, autosensData.time)) {
if (isEvent5minBack(siteChanges, autosensData.time)) {
data.clear()
pastSensitivity += "(SITECHANGE)"
}

View file

@ -8,10 +8,10 @@ import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.database.transactions.InsertTherapyEventIfNewTransaction
import info.nightscout.androidaps.interfaces.BgSourceInterface
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
@ -26,8 +26,6 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import org.json.JSONException
import org.json.JSONObject
import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
@ -36,8 +34,7 @@ import javax.inject.Singleton
class EversensePlugin @Inject constructor(
injector: HasAndroidInjector,
resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger,
private val databaseHelper: DatabaseHelperInterface
aapsLogger: AAPSLogger
) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE)
.fragmentClass(BGSourceFragment::class.java.name)
@ -139,20 +136,18 @@ class EversensePlugin @Inject constructor(
aapsLogger.debug(LTag.BGSOURCE, "calibrationTimestamps" + Arrays.toString(calibrationTimestamps))
aapsLogger.debug(LTag.BGSOURCE, "calibrationRecordNumbers" + Arrays.toString(calibrationRecordNumbers))
for (i in calibrationGlucoseLevels.indices) {
try {
if (eversensePlugin.databaseHelper.getCareportalEventFromTimestamp(calibrationTimestamps[i]) == null) {
val data = JSONObject()
data.put("enteredBy", "AndroidAPS-Eversense")
data.put("created_at", DateUtil.toISOString(calibrationTimestamps[i]))
data.put("eventType", CareportalEvent.BGCHECK)
data.put("glucoseType", "Finger")
data.put("glucose", calibrationGlucoseLevels[i])
data.put("units", Constants.MGDL)
nsUpload.uploadCareportalEntryToNS(data, calibrationTimestamps[i])
}
} catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e)
}
eversensePlugin.disposable += repository.runTransactionForResult(InsertTherapyEventIfNewTransaction(
timestamp = calibrationTimestamps[i],
type = TherapyEvent.Type.FINGER_STICK_BG_VALUE,
glucose = calibrationGlucoseLevels[i].toDouble(),
glucoseType = TherapyEvent.MeterType.FINGER,
units = Constants.MGDL,
enteredBy = "AndroidAPS-Eversense"
)).subscribe({ result ->
result.inserted.forEach { nsUpload.uploadEvent(it) }
}, {
aapsLogger.error(LTag.BGSOURCE, "Error while saving therapy event", it)
})
}
}
}

View file

@ -4,7 +4,7 @@ import android.content.Context
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.CommandQueueProvider
@ -14,6 +14,7 @@ import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.roundToInt
@Singleton
class CarbsGenerator @Inject constructor(
@ -28,9 +29,9 @@ class CarbsGenerator @Inject constructor(
val ticks = duration * 4 //duration guaranteed to be integer greater zero
for (i in 0 until ticks) {
val carbTime = startTime + i * 15 * 60 * 1000
val smallCarbAmount = Math.round(1.0 * remainingCarbs / (ticks - i)).toInt() //on last iteration (ticks-i) is 1 -> smallCarbAmount == remainingCarbs
val smallCarbAmount = (1.0 * remainingCarbs / (ticks - i)).roundToInt() //on last iteration (ticks-i) is 1 -> smallCarbAmount == remainingCarbs
remainingCarbs -= smallCarbAmount.toLong()
if (smallCarbAmount > 0) createCarb(smallCarbAmount, carbTime, CareportalEvent.MEALBOLUS, notes)
if (smallCarbAmount > 0) createCarb(smallCarbAmount, carbTime, TherapyEvent.Type.MEAL_BOLUS.text, notes)
}
}

View file

@ -9,33 +9,43 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.transactions.InvalidateAAPSStartedTherapyEventTransaction
import info.nightscout.androidaps.database.transactions.InvalidateTherapyEventTransaction
import info.nightscout.androidaps.database.entities.UserEntry.*
import info.nightscout.androidaps.databinding.TreatmentsCareportalFragmentBinding
import info.nightscout.androidaps.databinding.TreatmentsCareportalItemBinding
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.events.EventCareportalEventChange
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.events.EventTherapyEventChange
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.UploadQueue
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsCareportalFragment.RecyclerViewAdapter.CareportalEventsViewHolder
import info.nightscout.androidaps.plugins.treatments.events.EventTreatmentUpdateGui
import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsCareportalFragment.RecyclerViewAdapter.TherapyEventsViewHolder
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.Translator
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.Completable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import io.reactivex.rxkotlin.subscribeBy
import java.util.concurrent.TimeUnit
import javax.inject.Inject
class TreatmentsCareportalFragment : DaggerFragment() {
private val disposable = CompositeDisposable()
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var sp: SP
@Inject lateinit var resourceHelper: ResourceHelper
@ -46,9 +56,13 @@ class TreatmentsCareportalFragment : DaggerFragment() {
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var buildHelper: BuildHelper
@Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var repository: AppRepository
@Inject lateinit var uel: UserEntryLogger
private val disposable = CompositeDisposable()
private val millsToThePast = T.days(30).msecs()
private var _binding: TreatmentsCareportalFragmentBinding? = null
// This property is only valid between onCreateView and
@ -62,12 +76,17 @@ class TreatmentsCareportalFragment : DaggerFragment() {
super.onViewCreated(view, savedInstanceState)
binding.recyclerview.setHasFixedSize(true)
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
binding.recyclerview.adapter = RecyclerViewAdapter(databaseHelper.getCareportalEvents(false))
binding.refreshFromNightscout.setOnClickListener {
activity?.let { activity ->
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal), resourceHelper.gs(R.string.refresheventsfromnightscout) + " ?", Runnable {
uel.log(Action.CAREPORTAL_NS_REFRESH)
databaseHelper.resetCareportalEvents()
disposable += Completable.fromAction { repository.deleteAllTherapyEventsEntries() }
.subscribeOn(aapsSchedulers.io)
.observeOn(aapsSchedulers.main)
.subscribeBy(
onError = { aapsLogger.error("Error removing entries", it) },
onComplete = { rxBus.send(EventTherapyEventChange()) }
)
rxBus.send(EventNSClientRestart())
})
}
@ -76,34 +95,58 @@ class TreatmentsCareportalFragment : DaggerFragment() {
activity?.let { activity ->
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal), resourceHelper.gs(R.string.careportal_removestartedevents), Runnable {
uel.log(Action.RESTART_EVENTS_REMOVED)
val events = databaseHelper.getCareportalEvents(false)
for (i in events.indices) {
val careportalEvent = events[i]
if (careportalEvent.json.contains(resourceHelper.gs(R.string.androidaps_start))) {
if (NSUpload.isIdValid(careportalEvent._id))
nsUpload.removeCareportalEntryFromNS(careportalEvent._id)
else
uploadQueue.removeID("dbAdd", careportalEvent._id)
databaseHelper.delete(careportalEvent)
}
}
// val events = databaseHelper.getCareportalEvents(false)
repository.runTransactionForResult(InvalidateAAPSStartedTherapyEventTransaction())
.subscribe({ result ->
result.invalidated.forEach { event ->
if (NSUpload.isIdValid(event.interfaceIDs.nightscoutId))
nsUpload.removeCareportalEntryFromNS(event.interfaceIDs.nightscoutId)
else
uploadQueue.removeID("dbAdd", event.timestamp.toString())
}
}, {
aapsLogger.error(LTag.BGSOURCE, "Error while invalidating therapy event", it)
})
}, null)
}
}
val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode()
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.GONE
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
rxBus.send(EventTreatmentUpdateGui())
}
}
fun swapAdapter() {
val now = System.currentTimeMillis()
if (binding.showInvalidated.isChecked)
repository
.getTherapyEventDataIncludingInvalidFromTime(now - millsToThePast, false)
.observeOn(aapsSchedulers.main)
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
else
repository
.getTherapyEventDataFromTime(now - millsToThePast, false)
.observeOn(aapsSchedulers.main)
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
}
@Synchronized
override fun onResume() {
super.onResume()
swapAdapter()
disposable.add(rxBus
.toObservable(EventCareportalEventChange::class.java)
.toObservable(EventTherapyEventChange::class.java)
.observeOn(aapsSchedulers.main)
.subscribe({ updateGui() }, fabricPrivacy::logException)
.debounce(1L, TimeUnit.SECONDS)
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
)
updateGui()
disposable += rxBus
.toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above
.observeOn(aapsSchedulers.io)
.debounce(1L, TimeUnit.SECONDS)
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
}
@Synchronized
@ -115,53 +158,53 @@ class TreatmentsCareportalFragment : DaggerFragment() {
@Synchronized
override fun onDestroyView() {
super.onDestroyView()
binding.recyclerview.adapter = null // avoid leaks
_binding = null
}
private fun updateGui() {
if (_binding == null) return
binding.recyclerview.swapAdapter(RecyclerViewAdapter(databaseHelper.getCareportalEvents(false)), false)
}
inner class RecyclerViewAdapter internal constructor(private var list: List<TherapyEvent>) : RecyclerView.Adapter<TherapyEventsViewHolder>() {
inner class RecyclerViewAdapter internal constructor(private var careportalEventList: List<CareportalEvent>) : RecyclerView.Adapter<CareportalEventsViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): CareportalEventsViewHolder {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): TherapyEventsViewHolder {
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_careportal_item, viewGroup, false)
return CareportalEventsViewHolder(v)
return TherapyEventsViewHolder(v)
}
override fun onBindViewHolder(holder: CareportalEventsViewHolder, position: Int) {
val careportalEvent = careportalEventList[position]
holder.binding.ns.visibility = if (NSUpload.isIdValid(careportalEvent._id)) View.VISIBLE else View.GONE
holder.binding.date.text = dateUtil.dateAndTimeString(careportalEvent.date)
holder.binding.duration.text = if (careportalEvent.durationInMsec() == 0L) "" else DateUtil.niceTimeScalar(careportalEvent.durationInMsec(), resourceHelper)
holder.binding.note.text = careportalEvent.notes
holder.binding.type.text = translator.translate(careportalEvent.eventType)
holder.binding.remove.tag = careportalEvent
override fun onBindViewHolder(holder: TherapyEventsViewHolder, position: Int) {
val therapyEvent = list[position]
holder.binding.ns.visibility = (therapyEvent.interfaceIDs.nightscoutId != null).toVisibility()
holder.binding.invalid.visibility = therapyEvent.isValid.not().toVisibility()
holder.binding.date.text = dateUtil.dateAndTimeString(therapyEvent.timestamp)
holder.binding.duration.text = if (therapyEvent.duration == 0L) "" else DateUtil.niceTimeScalar(therapyEvent.duration, resourceHelper)
holder.binding.note.text = therapyEvent.note
holder.binding.type.text = translator.translate(therapyEvent.type.text)
holder.binding.remove.tag = therapyEvent
}
override fun getItemCount(): Int {
return careportalEventList.size
return list.size
}
inner class CareportalEventsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
inner class TherapyEventsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val binding = TreatmentsCareportalItemBinding.bind(view)
init {
binding.remove.setOnClickListener { v: View ->
val careportalEvent = v.tag as CareportalEvent
val therapyEvent = v.tag as TherapyEvent
activity?.let { activity ->
val text = resourceHelper.gs(R.string.eventtype) + ": " + translator.translate(careportalEvent.eventType) + "\n" +
resourceHelper.gs(R.string.notes_label) + ": " + careportalEvent.notes + "\n" +
resourceHelper.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(careportalEvent.date)
val text = resourceHelper.gs(R.string.eventtype) + ": " + translator.translate(therapyEvent.type.text) + "\n" +
resourceHelper.gs(R.string.notes_label) + ": " + (therapyEvent.note ?: "") + "\n" +
resourceHelper.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(therapyEvent.timestamp)
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.removerecord), text, Runnable {
uel.log(Action.CAREPORTAL_REMOVED, careportalEvent.notes, ValueWithUnit(careportalEvent.eventType, Units.CPEvent), ValueWithUnit(careportalEvent.date, Units.Timestamp))
if (NSUpload.isIdValid(careportalEvent._id))
nsUpload.removeCareportalEntryFromNS(careportalEvent._id)
else
uploadQueue.removeID("dbAdd", careportalEvent._id)
databaseHelper.delete(careportalEvent)
uel.log(Action.CAREPORTAL_REMOVED, therapyEvent.note ?: "", ValueWithUnit(therapyEvent.type.text, Units.CPEvent), ValueWithUnit(therapyEvent.timestamp, Units.Timestamp))
disposable += repository.runTransactionForResult(InvalidateTherapyEventTransaction(therapyEvent.id))
.subscribe({
val id = therapyEvent.interfaceIDs.nightscoutId
if (NSUpload.isIdValid(id)) nsUpload.removeCareportalEntryFromNS(id)
else uploadQueue.removeID("dbAdd", therapyEvent.timestamp.toString())
}, {
aapsLogger.error(LTag.BGSOURCE, "Error while invalidating therapy event", it)
})
}, null)
}
}

View file

@ -11,8 +11,8 @@ import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.entities.UserEntry.*
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.events.EventRefreshOverview
import info.nightscout.androidaps.interfaces.*
@ -23,6 +23,7 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.CarbTimer
@ -58,6 +59,7 @@ class BolusWizard @Inject constructor(
@Inject lateinit var config: Config
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var carbTimer: CarbTimer
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
init {
injector.androidInjector().inject(this)
@ -182,7 +184,7 @@ class BolusWizard @Inject constructor(
}
// Insulin from 15 min trend
glucoseStatus = GlucoseStatus(injector).glucoseStatusData
glucoseStatus = glucoseStatusProvider.glucoseStatusData
glucoseStatus?.let {
if (useTrend) {
trend = it.shortAvgDelta
@ -337,7 +339,7 @@ class BolusWizard @Inject constructor(
val confirmMessage = confirmMessageAfterConstraints(advisor = true)
OKDialog.showConfirmation(ctx, resourceHelper.gs(R.string.boluswizard), confirmMessage, {
DetailedBolusInfo().apply {
eventType = CareportalEvent.CORRECTIONBOLUS
eventType = TherapyEvent.Type.CORRECTION_BOLUS.text
insulin = insulinAfterConstraints
carbs = 0.0
context = ctx
@ -401,7 +403,7 @@ class BolusWizard @Inject constructor(
}
}
DetailedBolusInfo().apply {
eventType = CareportalEvent.BOLUSWIZARD
eventType = TherapyEvent.Type.BOLUS_WIZARD.text
insulin = insulinAfterConstraints
carbs = this@BolusWizard.carbs.toDouble()
context = ctx

View file

@ -10,6 +10,7 @@ import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil
@ -32,6 +33,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
@Inject lateinit var repository: AppRepository
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
lateinit var storage: JSONObject
var position: Int = -1
@ -114,7 +116,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec
}
if (loopPlugin.isEnabled(loopPlugin.getType()) && loopPlugin.isSuperBolus) superBolus = false
// Trend
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
var trend = false
if (useTrend() == YES) {
trend = true

View file

@ -1,4 +1,5 @@
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
@ -14,7 +15,7 @@
android:id="@+id/refresh_from_nightscout"
style="?android:attr/buttonStyle"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:drawableStart="@drawable/ic_refresh"
@ -24,12 +25,28 @@
android:id="@+id/remove_androidaps_started_events"
style="?android:attr/buttonStyle"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:drawableStart="@drawable/ic_remove"
android:text="@string/careportal_removestartedevents" />
<CheckBox
android:id="@+id/show_invalidated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:checked="false"
android:paddingEnd="5dp"
tools:ignore="RtlSymmetry" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@string/show_calculation"
app:srcCompat="@drawable/ic_visibility" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView

View file

@ -38,14 +38,6 @@
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="HardcodedText,RtlSymmetry" />
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingEnd="10dp"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/type"
android:layout_width="wrap_content"
@ -72,6 +64,15 @@
android:textColor="@color/colorSetTempButton"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/invalid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:text="@string/invalid"
android:textColor="@android:color/holo_red_light" />
</LinearLayout>
<LinearLayout
@ -79,16 +80,24 @@
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingStart="10dp"
android:paddingEnd="10dp"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/note"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:text="Activity"
tools:ignore="HardcodedText" />
tools:ignore="HardcodedText,RtlSymmetry" />
<TextView
android:id="@+id/remove"
@ -104,10 +113,10 @@
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="5dp"
android:background="@color/list_delimiter" />
</LinearLayout>

View file

@ -153,7 +153,6 @@
<string name="smscommunicator_loophasbeenenabled">Loop is geaktiveerd</string>
<string name="smscommunicator_loopisenabled">Lus geaktiveer</string>
<string name="valuelimitedto">%1$.2f beperk tot %2$.2f</string>
<string name="valueoutofrange">Waarde %1$s is uit harde perke</string>
<string name="smscommunicator_remotecommandnotallowed">Afstandbeheerde bevel word nie toegelaat nie</string>
<string name="smscommunicator_remotebolusnotallowed">Afstandbeheerde bolus nie beskikbaar nie. Probeer later weer.</string>
<string name="smscommunicator_profilereplywithcode">Om profiel te verander na %1$s %2$d%% antwoord met %3$s</string>

View file

@ -194,7 +194,6 @@
<string name="smscommunicator_loophasbeenenabled">APS е активиран</string>
<string name="smscommunicator_loopisenabled">APS е включен</string>
<string name="valuelimitedto">%1$.2f ограничен до %2$.2f</string>
<string name="valueoutofrange">Стойността %1$s е извън ограниченията</string>
<string name="smscommunicator_pumpconnectwithcode">За свързване с помпа отговорете с код %1$s</string>
<string name="smscommunicator_pumpconnectfail">Връзката с помпата е неуспешна</string>
<string name="smscommunicator_pumpdisconnectwithcode">За да спрете помпата за %1$d минути отговорете с код %2$s</string>

View file

@ -194,7 +194,7 @@
<string name="smscommunicator_loophasbeenenabled">Smyčka byla povolena</string>
<string name="smscommunicator_loopisenabled">Smyčka je povolena</string>
<string name="valuelimitedto">%1$.2f omezeno na %2$.2f</string>
<string name="valueoutofrange">Hodnota %1$s je mimo přednastavený rozsah</string>
<string name="valueoutofrange">»%1$s« je mimo pevně nastavené limity</string>
<string name="smscommunicator_pumpconnectwithcode">Chcete-li připojit pumpu, odpovězte pomocí SMS s kódem %1$s</string>
<string name="smscommunicator_pumpconnectfail">Připojení k pumpě selhalo</string>
<string name="smscommunicator_pumpdisconnectwithcode">Chcete-li odpojit pumpu na %1$d minut, odpovězte pomocí SMS s kódem %2$s</string>
@ -904,4 +904,14 @@
<string name="email_address">E-mailová adresa</string>
<string name="privacy_settings">Nastavení soukromí</string>
<string name="privacy_summary">Pokud chcete být upozorněni na selhání aplikace, můžete zadat volitelně e-mailovou adresu. Toto není automatizovaná služba. Vývojáři vás budou kontaktovat v nebezpečných situacích.</string>
<string name="profile_low_target">Dolní cíl profilu</string>
<string name="profile_high_target">Horní cíl profilu</string>
<string name="temp_target_low_target">Dolní hodnota dočasného cíle</string>
<string name="temp_target_high_target">Horní hodnota dočasného cíle</string>
<string name="temp_target_value">Hodnota dočasného cíle</string>
<string name="profile_dia">Hodnota DIA profilu</string>
<string name="profile_sensitivity_value">Hodnota citlivosti profilu</string>
<string name="profile_max_daily_basal_value">Maximální hodnota bazálu profilu</string>
<string name="current_basal_value">Aktuální hodnota bazálu</string>
<string name="profile_carbs_ratio_value">Inzulino-sacharidový poměr profilu</string>
</resources>

View file

@ -194,7 +194,7 @@
<string name="smscommunicator_loophasbeenenabled">Lopp wurde aktiviert.</string>
<string name="smscommunicator_loopisenabled">Loop ist aktiviert.</string>
<string name="valuelimitedto">%1$.2f limitiert auf %2$.2f</string>
<string name="valueoutofrange">Wert %1$s ist außerhalb des festen Limits.</string>
<string name="valueoutofrange">»%1$s« ist außerhalb der fest programmierten Grenzen</string>
<string name="smscommunicator_pumpconnectwithcode">Um die Pumpe zu verbinden, antworte mit dem Code %1$s</string>
<string name="smscommunicator_pumpconnectfail">Verbindung zur Pumpe fehlgeschlagen</string>
<string name="smscommunicator_pumpdisconnectwithcode">Um die Verbindung zur Pumpe für %1$d Minuten zu trennen, antworte mit dem Code %2$s</string>
@ -905,4 +905,14 @@ Unerwartetes Verhalten.</string>
<string name="email_address">EMailAdresse</string>
<string name="privacy_settings">Privatsphäre-Einstellungen</string>
<string name="privacy_summary">Du kannst optional eine E-Mail-Adresse angeben, wenn Du bei Absturzberichten kontaktiert werden möchtest. Dies ist keine Automatik, Du wirst von den Entwicklern in gefährlichen Situationen kontaktiert. </string>
<string name="profile_low_target">Profil unteres Ziel</string>
<string name="profile_high_target">Profil oberes Ziel</string>
<string name="temp_target_low_target">Temp. Ziel unterer Wert</string>
<string name="temp_target_high_target">Temp. Ziel oberer Wert</string>
<string name="temp_target_value">Temp. Ziel Wert</string>
<string name="profile_dia">Profil Insulinwirkdauer</string>
<string name="profile_sensitivity_value">Profil Sensitivitätswert</string>
<string name="profile_max_daily_basal_value">Profil max. Basalwert</string>
<string name="current_basal_value">Aktueller Basalwert</string>
<string name="profile_carbs_ratio_value">Profil KH-Faktor</string>
</resources>

View file

@ -155,7 +155,6 @@
<string name="smscommunicator_loophasbeenenabled">Το κύκλωμα ενεργοποιήθηκε</string>
<string name="smscommunicator_loopisenabled">Κύκλωμα ενεργοποιημένο</string>
<string name="valuelimitedto">Το %1$.2f περιορίζεται σε %2$.2f</string>
<string name="valueoutofrange">Η τιμή %1$s είναι έξω από τα όρια</string>
<string name="smscommunicator_remotecommandnotallowed">Δεν επιτρέπεται απομακρυσμένη εντολή</string>
<string name="smscommunicator_remotebolusnotallowed">Απομακρυσμένο bolus μη διαθέσιμο. Δοκιμάστε ξανά αργότερα.</string>
<string name="smscommunicator_profilereplywithcode">Για αλλαγή προφίλ σε %1$s %2$d%% στείλτε κωδικό %3$s</string>

View file

@ -194,7 +194,6 @@
<string name="smscommunicator_loophasbeenenabled">Lazo se ha activado</string>
<string name="smscommunicator_loopisenabled">Lazo activo</string>
<string name="valuelimitedto">%1$.2f limitado a %2$.2f</string>
<string name="valueoutofrange">El valor %1$s está fuera de límites</string>
<string name="smscommunicator_pumpconnectwithcode">Para conectar la infusora responder con el código %1$s</string>
<string name="smscommunicator_pumpconnectfail">Error al conectar a la bomba</string>
<string name="smscommunicator_pumpdisconnectwithcode">Para desconectar la bomba durante %1$dminutos responde con el código %2$s</string>

View file

@ -195,7 +195,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="smscommunicator_loophasbeenenabled">La Boucle a été activée</string>
<string name="smscommunicator_loopisenabled">La Boucle est activée</string>
<string name="valuelimitedto">%1$.2f limité à %2$.2f</string>
<string name="valueoutofrange">La valeur %1$s est en dehors des limites</string>
<string name="valueoutofrange">\"%1$s\" est en dehors des limites</string>
<string name="smscommunicator_pumpconnectwithcode">Pour connecter la pompe, renvoyez le code %1$s</string>
<string name="smscommunicator_pumpconnectfail">Echec de la connexion pompe</string>
<string name="smscommunicator_pumpdisconnectwithcode">Pour déconnecter la pompe pendant %1$d min, renvoyez le code %2$s</string>
@ -905,4 +905,14 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="email_address">Adresse e-mail</string>
<string name="privacy_settings">Paramètres de confidentialité</string>
<string name="privacy_summary">Vous pouvez fournir une adresse e-mail facultative si vous voulez être informé des plantages de l\'application. Ce n\'est pas un service automatisé. Vous serez contacté par les développeurs dans des situations dangereuses.</string>
<string name="profile_low_target">Cible basse du profil</string>
<string name="profile_high_target">Cible haute du profil</string>
<string name="temp_target_low_target">Valeur basse de cible temporaire</string>
<string name="temp_target_high_target">Valeur haute de cible temporaire</string>
<string name="temp_target_value">Valeur de cible temporaire</string>
<string name="profile_dia">Valeur DAI du profil</string>
<string name="profile_sensitivity_value">Valeur de sensibilité du profil</string>
<string name="profile_max_daily_basal_value">Basale maximale du profil</string>
<string name="current_basal_value">Basale actuelle</string>
<string name="profile_carbs_ratio_value">Rapport glucides/insuline de profil</string>
</resources>

View file

@ -194,7 +194,7 @@
<string name="smscommunicator_loophasbeenenabled">Il loop è stato abilitato</string>
<string name="smscommunicator_loopisenabled">Il loop è abilitato</string>
<string name="valuelimitedto">%1$.2f limitato a %2$.2f</string>
<string name="valueoutofrange">Il valore %1$s è fuori limite massimo</string>
<string name="valueoutofrange">»%1$s« è fuori dai limiti consentiti</string>
<string name="smscommunicator_pumpconnectwithcode">Per connettere il micro rispondi col codice %1$s</string>
<string name="smscommunicator_pumpconnectfail">Connessione al micro fallita</string>
<string name="smscommunicator_pumpdisconnectwithcode">Per disconnettere il micro per %1$d minuti rispondi col codice %2$s</string>
@ -904,4 +904,14 @@
<string name="email_address">Indirizzo email</string>
<string name="privacy_settings">Impostazioni privacy</string>
<string name="privacy_summary">Puoi fornire un indirizzo e-mail opzionale se desideri essere avvisato in caso di arresti anomali dell\'app. Questo non è un servizio automatizzato. Sarai contattato dagli sviluppatori in situazioni pericolose.</string>
<string name="profile_low_target">Target basso (profilo)</string>
<string name="profile_high_target">Target alto (profilo)</string>
<string name="temp_target_low_target">Valore inferiore target temporaneo</string>
<string name="temp_target_high_target">Valore superiore target temporaneo</string>
<string name="temp_target_value">Valore target temporaneo</string>
<string name="profile_dia">Valore DIA (profilo)</string>
<string name="profile_sensitivity_value">Valore sensibilità (profilo)</string>
<string name="profile_max_daily_basal_value">Valore max basale (profilo)</string>
<string name="current_basal_value">Valore basale corrente</string>
<string name="profile_carbs_ratio_value">Valore rapporto CHO (profilo)</string>
</resources>

View file

@ -14,7 +14,7 @@
<string name="objectives_maxiobzero_objective">מתחילים לסגור את הלולאה עם השהיה עקב רמת גלוקוז נמוכה</string>
<string name="objectives_maxiobzero_gate">הרץ בלולאה סגורה עם ערך IOB מקסימלי = 0 למשך מספר ימים, עם מעט ארועי השהיה עקב גלוקוז נמוך (LGS)</string>
<string name="objectives_maxiob_objective">כוונון הלולאה הסגורה, תוך העלאה של ערך ה- IOB מעל 0 ובסופו של דבר הורדת ערכי המטרה של רמת הסוכר</string>
<string name="objectives_maxiob_gate">לפני הורדת ערך רמת הסוכר, הפעל במשך מס\' ימים, עם לפחות לילה אחד ללא התרעת רמת סוכר נמוכה</string>
<string name="objectives_maxiob_gate">לפני הורדת ערך רמת הסוכר, הפעילו במשך מס\' ימים, עם לפחות לילה אחד ללא התרעת רמת סוכר נמוכה</string>
<string name="objectives_autosens_objective">במידת הצורך, בצעו התאמת בזאלי ויחסים, ולאחר מכן הפעילו את Autosens</string>
<string name="objectives_autosens_gate">שבוע של הפעלה מוצלחת של הלולאה במשך שעות היום, עם הוספת ערכי פחמימות רגילים</string>
<string name="objectives_ama_objective">הפעלת פונקציות נוספות לשימוש במשך היום, לדוגמה AMA (סיוע ארוחות מתקדם)</string>

View file

@ -194,7 +194,7 @@
<string name="smscommunicator_loophasbeenenabled">הלולאה הופעלה</string>
<string name="smscommunicator_loopisenabled">לולאה פעילה</string>
<string name="valuelimitedto">%1$.2f מוגבלת ל- %2$.2f</string>
<string name="valueoutofrange">ערך %1$s הינו מחוץ לתחום</string>
<string name="valueoutofrange">»הערך %1$s« מחוץ לתחום הקשיח</string>
<string name="smscommunicator_pumpconnectwithcode">לחיבור המשאבה יש להשיב עם הקוד %1$s</string>
<string name="smscommunicator_pumpconnectfail">החיבור אל המשאבה נכשל</string>
<string name="smscommunicator_pumpdisconnectwithcode">לניתוק המשאבה למשך %1$d דקות השיבו עם הקוד %2$s</string>
@ -520,7 +520,7 @@
<string name="apsselected">נבחר APS</string>
<string name="nsclienthaswritepermission">ל-NSClient יש הרשאת כתיבה</string>
<string name="closedmodeenabled">מצב סגור מופעל</string>
<string name="maxiobset">IOB מקסימלי הוגדר כראוי</string>
<string name="maxiobset">ערך IOB מקסימלי הוגדר כראוי</string>
<string name="hasbgdata">ערכי סוכר זמינים מהמקור הנבחר</string>
<string name="extendedbolusdeliveryerror">שגיאה במתן הבולוס הממושך</string>
<string name="enablesmbalways">הפעלת SMB תמיד</string>
@ -586,8 +586,8 @@
<string name="smbdisabledinpreferences">SMB מושבת בהעדפות</string>
<string name="uamdisabledinpreferences">UAM מושבת בהעדפות</string>
<string name="uamdisabledoref1notselected">UAM מושבת מפני שהוא מסתמך על תוסף רגישות של Oref1</string>
<string name="maxbasalmultiplier">מכפלת בזאלי מירבי</string>
<string name="maxdailybasalmultiplier">מכפלת בזאלי יומי מירבי</string>
<string name="maxbasalmultiplier">מכפלת בזאלי מרבי</string>
<string name="maxdailybasalmultiplier">מכפלת בזאלי יומי מרבי</string>
<string name="smb_frequency_exceeded">ניתן בולוס ב-3 הדקות האחרונות, מדלג על SMB</string>
<string name="basal_set_correctly">הבזאלי הוגדר כהלכה</string>
<string name="limitingextendedbolus">הגבלת בולוס ממושך ל- %1$.1f יח\' בגלל %2$s</string>
@ -627,7 +627,7 @@
<string name="openapsama_autosens_max">יחס Autosens מקסימלי</string>
<string name="openapsama_autosens_min">יחס Autosens מינימלי</string>
<string name="openapsama_bolussnooze_dia_divisor">נמנום בולוס - מחלק משך פעילות אינסולין</string>
<string name="openapsama_max_daily_safety_multiplier">מכפלת בטיחות בזאלי יומי מירבי</string>
<string name="openapsama_max_daily_safety_multiplier">מכפלת בטיחות בזאלי יומי מרבי</string>
<string name="openapsama_current_basal_safety_multiplier">מכפלת בטיחות בזאלי נוכחי</string>
<string name="value_unavailable_short">לא זמין</string>
<string name="virtualpump_type">סוג משאבה וירטואלית</string>
@ -904,4 +904,14 @@
<string name="email_address">כתובת דוא\"ל</string>
<string name="privacy_settings">הגדרות פרטיות</string>
<string name="privacy_summary">אם תרצו, תוכלו לספק כתובת דוא\"ל כדי לקבל דיווח על קריסות יישום. שירות זה אינו אוטומטי. המפתחים יצרו איתכם קשר במצבים מסוכנים.</string>
<string name="profile_low_target">ערך המטרה הנמוך של הפרופיל</string>
<string name="profile_high_target">ערך המטרה הגבוה של הפרופיל</string>
<string name="temp_target_low_target">ערך תחתון של המטרה הזמנית</string>
<string name="temp_target_high_target">ערך עליון של המטרה הזמנית</string>
<string name="temp_target_value">ערך המטרה הזמני</string>
<string name="profile_dia">ערך DIA של הפרופיל</string>
<string name="profile_sensitivity_value">ערך הרגישות של הפרופיל</string>
<string name="profile_max_daily_basal_value">ערך מינון בזאלי מרבי של הפרופיל</string>
<string name="current_basal_value">מינון בזאלי נוכחי</string>
<string name="profile_carbs_ratio_value">יחס הפחמימות של הפרופיל</string>
</resources>

View file

@ -166,7 +166,6 @@
<string name="smscommunicator_loophasbeenenabled">Loop가 실행되었습니다.</string>
<string name="smscommunicator_loopisenabled">Loop가 실행중입니다.</string>
<string name="valuelimitedto">%1$.2f, %2$.2f으로 제한됨</string>
<string name="valueoutofrange">%1$s값이 하드한계를 벗어났습니다</string>
<string name="smscommunicator_remotecommandnotallowed">원격 명령이 허가되지 않았습니다</string>
<string name="smscommunicator_remotebolusnotallowed">원격 주입이 불가능합니다. 나중에 다시 시도해주세요.</string>
<string name="smscommunicator_profilereplywithcode">프로파일 %1$s %2$d%%로 변경하려면 %3$s 를 입력하고 답장하세요</string>

View file

@ -192,7 +192,6 @@
<string name="smscommunicator_loophasbeenenabled">Ciklas buvo įjungtas</string>
<string name="smscommunicator_loopisenabled">Ciklas įjungtas</string>
<string name="valuelimitedto">%1$.2f apribotas iki %2$.2f</string>
<string name="valueoutofrange">Vertė %1$s viršija griežtą limitą</string>
<string name="smscommunicator_pumpconnectwithcode">Pompos prijungimui atsakykite su kodu %1$s</string>
<string name="smscommunicator_pumpconnectfail">Nepavyko prisijungti prie pompos</string>
<string name="smscommunicator_pumpdisconnectwithcode">Norėdami atjungti pompą %1$d min., atsakykite kodu %2$s</string>

View file

@ -194,7 +194,6 @@
<string name="smscommunicator_loophasbeenenabled">Loop was ingeschakeld</string>
<string name="smscommunicator_loopisenabled">Loop is ingeschakeld</string>
<string name="valuelimitedto">%1$.2f gelimiteerd tot %2$.2f</string>
<string name="valueoutofrange">Waarde %1$s valt buiten de toegestane harde limieten</string>
<string name="smscommunicator_pumpconnectwithcode">Om verbinding te maken met pomp antwoord met code %1$s</string>
<string name="smscommunicator_pumpconnectfail">Verbinding maken met pomp is mislukt</string>
<string name="smscommunicator_pumpdisconnectwithcode">Om de pomp te ontkoppelen gedurende %1$d minuten antwoord met code %2$s</string>

View file

@ -194,7 +194,7 @@
<string name="smscommunicator_loophasbeenenabled">Loop har blitt aktivert</string>
<string name="smscommunicator_loopisenabled">Loop er aktivert</string>
<string name="valuelimitedto">%1$.2f begrenset til %2$.2f</string>
<string name="valueoutofrange">Verdien %1$s er utenfor angitt begrensning</string>
<string name="valueoutofrange">»%1$s« er utenfor lovlige grenseverdier</string>
<string name="smscommunicator_pumpconnectwithcode">For å koble til pumpen, svar med kode %1$s</string>
<string name="smscommunicator_pumpconnectfail">Tilkobling til pumpen mislyktes</string>
<string name="smscommunicator_pumpdisconnectwithcode">For å koble fra pumpen i %1$d minutter, svar med koden %2$s</string>
@ -904,4 +904,14 @@
<string name="email_address">E-postadresse</string>
<string name="privacy_settings">Personverninnstillinger</string>
<string name="privacy_summary">Du kan oppgi valgfri e-postadresse hvis du ønsker å bli varslet om krasj. Dette er ikke en automatisert tjeneste. Du vil bli kontaktet av utviklere ved farlige hendelser.</string>
<string name="profile_low_target">Profil lavt blodsukkermål</string>
<string name="profile_high_target">Profil høyt blodsukkermål</string>
<string name="temp_target_low_target">Midlertidig mål bunnverdi</string>
<string name="temp_target_high_target">Midlertidig mål toppverdi</string>
<string name="temp_target_value">Midlertidig målverdi</string>
<string name="profile_dia">Profil insulinvarighet (DIA)</string>
<string name="profile_sensitivity_value">Profil sensitivitetsverdi (IF)</string>
<string name="profile_max_daily_basal_value">Profil maksimal basal dose</string>
<string name="current_basal_value">Aktiv basal dose</string>
<string name="profile_carbs_ratio_value">Profil karbohydratfaktor (IK)</string>
</resources>

View file

@ -194,7 +194,6 @@
<string name="smscommunicator_loophasbeenenabled">Pętla (Loop) została włączona</string>
<string name="smscommunicator_loopisenabled">Pętla (Loop) jest włączona</string>
<string name="valuelimitedto">%1$.2f ograniczone do %2$.2f</string>
<string name="valueoutofrange">Wartość %1$s jest poza dopuszczalną granicą</string>
<string name="smscommunicator_pumpconnectwithcode">Aby podłączyć pompę odpowiedz kodem %1$s</string>
<string name="smscommunicator_pumpconnectfail">Połączenie z pompą nie powiodło się</string>
<string name="smscommunicator_pumpdisconnectwithcode">Aby odłączyć pompę na %1$d minut odpowiedz kodem %2$s</string>

View file

@ -181,7 +181,6 @@
<string name="smscommunicator_loophasbeenenabled">Loop foi ativado</string>
<string name="smscommunicator_loopisenabled">Loop ativado</string>
<string name="valuelimitedto">%1$.2f limitado a %2$.2f</string>
<string name="valueoutofrange">O valor %1$s está fora dos limites permitidos</string>
<string name="smscommunicator_pumpdisconnected">Bomba desconectada</string>
<string name="smscommunicator_reconnect">Bomba reconectada</string>
<string name="smscommunicator_remotecommandnotallowed">O comando remoto não é permitido</string>

View file

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dia_whatmeansdia">O que é verdade sobre DIA?</string>
<string name="dia_label_exam">Duração da Acção de Insulina (DIA)</string>
<string name="dia_label_exam">Duração da Acção da Insulina (DIA)</string>
<string name="dia_profile">Deve definir o valor da DIA no seu perfil.</string>
<string name="dia_minimumis5h">O valor mínimo permitido são 5 horas.</string>
<string name="dia_hint1">https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html?#insulin</string>
<string name="dia_meaningisequaltodiapump">Se estiver satisfeito com o valor para a DIA que utilizou na bomba antes do AndroidAPS e funcionou bem, não há necessidade de alterar isso quando inicia o loop.</string>
<string name="dia_valuemustbedetermined">Deve determinar para si mesmo o valor adequado para a DIA.</string>
<string name="dia_meaningisequaltodiapump">Se estiver satisfeito com o valor da DIA que utilizava na bomba antes da AndroidAPS e que funcionava bem, não há necessidade de o alterar quando iniciar o loop.</string>
<string name="dia_valuemustbedetermined">Deve determinar para o seu valor adequado para a DIA.</string>
<string name="hypott_label">Hipo Alvo-Temp</string>
<string name="hypott_whenhypott">Qual é a principal razão para definir um alvo temporário?</string>
<string name="hypott_wrongbasal">Para corrigir hipos causadas por configurações de taxa de basal incorretas.</string>
@ -110,7 +110,7 @@
<string name="troubleshooting_hint2">https://www.facebook.com/groups/AndroidAPSUsers/</string>
<string name="troubleshooting_hint3">https://gitter.im/MilosKozak/AndroidAPS</string>
<string name="insulin_label">Plugins de Insulina</string>
<string name="insulin_ultrarapid">Qual insulina deve utilizar com o plugin Ultra-Rapid Oref?</string>
<string name="insulin_ultrarapid">Que insulina deve utilizar com o plugin Oref Ultra-Rápida ?</string>
<string name="insulin_fiasp">Fiasp®</string>
<string name="insulin_novorapid">NovoRapid®/Novolog®</string>
<string name="insulin_humalog">Humalog ®</string>
@ -193,8 +193,8 @@
<string name="profileswitch2_isfhigher">FSI será 20% maior.</string>
<string name="profileswitchtime_label">Troca de Perfil</string>
<string name="profileswitchtime_iwant">Se você se levanta 2 horas mais cedo do que o normal, como deve notificar o AndroidAPS da alteração no seu horário?</string>
<string name="profileswitchtime_2">Iniciar uma mudança de perfil com uma alteração de turno de 2</string>
<string name="profileswitchtime__2">Iniciar uma mudança de perfil com uma alteração de turno de -2</string>
<string name="profileswitchtime_2">Iniciar uma mudança de perfil com um deslocamento temporal de 2</string>
<string name="profileswitchtime__2">Iniciar uma mudança de perfil com uma deslocamento temporal de -2</string>
<string name="profileswitchtime_tt">Defina um alvo temporário de comer brevemente.</string>
<string name="profileswitchtime_100">Faça troca de perfil para mais de 100%. </string>
<string name="profileswitchtime_hint1">https://androidaps.readthedocs.io/en/latest/EN/Usage/Profiles.html?highlight=profile%20switch#timeshift</string>

View file

@ -33,7 +33,7 @@
<string name="description_pump_mdi">Integração para as pessoas que fazem múltiplas injeções diárias para a sua terapia de diabetes</string>
<string name="description_pump_virtual">Integração para as bombas que não têm qualquer driver ainda (Open Loop)</string>
<string name="description_sensitivity_aaps">A sensibilidade é calculada da mesma forma que Oref0, mas pode especificar o período de tempo para o passado. A absorção mínima de hidratos de carbono é calculada a partir do tempo máximo de absorção de hidratos de carbono das preferências.</string>
<string name="description_sensitivity_oref1">A sensibilidade é calculada a partir de dados das últimas 8h ou 24h (usando qualquer um que é mais sensível). Hidratos são cortados (se não absorvidos) após o tempo especificado nas preferências. O Plugin também calcula o UAM.</string>
<string name="description_sensitivity_oref1">A sensibilidade é calculada a partir de dados das últimas 8h ou 24h (usando o que é mais sensível). Os hidratos de carbono são descartados (se não absorvidos) após o tempo especificado nas preferências. O Plugin também calcula o RNA.</string>
<string name="description_sensitivity_weighted_average">A sensibilidade é calculada como uma média ponderada de desvios. Desvios mais recentes têm maior peso. A absorção mínima de hidratos de carbono é calculada a partir do tempo máximo de absorção de hidratos de carbono das preferências. Este algoritmo é o mais rápido em seguir as mudanças de sensibilidade.</string>
<string name="description_source_eversense">Receber valores Glicose da aplicação Eversense modificada.</string>
<string name="description_source_glimp">Receber valores Glicose do Glimp.</string>
@ -194,7 +194,7 @@
<string name="smscommunicator_loophasbeenenabled">Loop foi activado</string>
<string name="smscommunicator_loopisenabled">Loop activado</string>
<string name="valuelimitedto">%1$.2f limitado a %2$.2f</string>
<string name="valueoutofrange">O valor %1$s está fora dos limites permitidos</string>
<string name="valueoutofrange">»%1$s« está fora dos limites máximos</string>
<string name="smscommunicator_pumpconnectwithcode">Para ligar a bomba responda com o código %1$s</string>
<string name="smscommunicator_pumpconnectfail">Ligação à bomba falhou</string>
<string name="smscommunicator_pumpdisconnectwithcode">Para remover a bomba por %1$d minutos responda com o código %2$s</string>
@ -449,21 +449,21 @@
<string name="ns_localbroadcasts">Activar transmissões para outras aplicações (como xDrip+). Não habilite se tiver mais de uma instância de AAPS ou ClienteNS instalado!</string>
<string name="ns_localbroadcasts_title">Activar partilha local.</string>
<string name="openapssmb">OpenAPS SMB</string>
<string name="enableuam">Activar UAM</string>
<string name="enableuam">Activar RNA</string>
<string name="enablesmb">Activar SMB</string>
<string name="enablesmb_summary">Use Super Micro Boluses em vez de basal temp para uma acção mais rápida</string>
<string name="enableuam_summary">Detecção de Refeições Não Introduzidas</string>
<string name="insulin_oref_peak">Tempo Pico da curva de IOB</string>
<string name="enableuam_summary">Deteção de Refeições Não Anunciadas (RNA)</string>
<string name="insulin_oref_peak">Tempo do Pico da curva de IOB</string>
<string name="insulin_peak_time">Tempo Pico [min]</string>
<string name="free_peak_oref">Oref Pico-Livre</string>
<string name="rapid_acting_oref">Oref Acção Rápida</string>
<string name="ultrarapid_oref">Ultra-Rapid Oref</string>
<string name="rapid_acting_oref">Oref Acção-Rápida</string>
<string name="ultrarapid_oref">Oref Ultra-Rápida</string>
<string name="lyumjev">Lyumjev</string>
<string name="dia_too_short">Duração de Acção da Insulina (DIA) de %1$f demasiado curto - corrigido para %2$f!</string>
<string name="activate_profile">Activar perfil</string>
<string name="invalid">INVÁLIDO</string>
<string name="careportal_newnstreatment_percentage_label">Percentagem</string>
<string name="careportal_newnstreatment_timeshift_label">Alteração Turno</string>
<string name="careportal_newnstreatment_timeshift_label">Deslocamento temporal</string>
<string name="default_temptargets">Alvo-Temp padrão</string>
<string name="eatingsoon_duration">duração comerbreve</string>
<string name="eatingsoon_target">alvo comerbreve</string>
@ -500,8 +500,8 @@
<string name="wear_detailed_delta_summary">Mostrar delta com mais um ponto decimal</string>
<string name="smbinterval_summary">Com que frequência em min os SMBs serão dados</string>
<string name="smbmaxminutes_summary">Limite de minutos de basal para SMB</string>
<string name="uamsmbmaxminutes">UAM SMB máx minutos</string>
<string name="uamsmbmaxminutes_summary">Max minutos de basal para limitar SMB para UAM</string>
<string name="uamsmbmaxminutes">RNA SMB máx minutos</string>
<string name="uamsmbmaxminutes_summary">Max minutos de basal para limitar SMB para RNA</string>
<string name="carbsReqThreshold">Mínimo De Hidratos Necessários Para Sugestão</string>
<string name="carbsReqThreshold_summary">Mínimo de gramas de hidratos de carbono ara exibir um alerta de sugestão de hidratos. As sugestões de hidratos abaixo deste número não activarão uma notificação.</string>
<string name="dexcomg5_xdripupload_title">Enviar dados Glicose para xDrip+</string>
@ -584,8 +584,8 @@
<string name="closedmodedisabledinpreferences">Loop fecchado disabilitado nas preferências</string>
<string name="autosensdisabledinpreferences">Autosens desabilitado nas preferências</string>
<string name="smbdisabledinpreferences">SMB desactivado nas configurações</string>
<string name="uamdisabledinpreferences">UAM desactivado nas configurações</string>
<string name="uamdisabledoref1notselected">UAM desactivado porque confia no plugin de sensibilidade Oref1</string>
<string name="uamdisabledinpreferences">RNA desactivada nas configurações</string>
<string name="uamdisabledoref1notselected">RNA desactivada porque confia no plugin de sensibilidade Oref1</string>
<string name="maxbasalmultiplier">multiplicador de basal máx</string>
<string name="maxdailybasalmultiplier">multiplicador de basal máx diária</string>
<string name="smb_frequency_exceeded">Um bólus foi administrado nos últimos 3 minutos, a ignorar SMB</string>
@ -800,8 +800,8 @@
<string name="chartmenu">Menu do Gráfico</string>
<string name="loop_smbrequest_time_label">Hora de solicitação SMB</string>
<string name="loop_smbexecution_time_label">Hora de execução do SMB</string>
<string name="loop_tbrrequest_time_label">Hora de solicitação Basal Temp</string>
<string name="loop_tbrexecution_time_label">Hora de execução Basal Temp</string>
<string name="loop_tbrrequest_time_label">Hora de solicitação da BT</string>
<string name="loop_tbrexecution_time_label">Hora de execução da BT</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">da app Authenticator para: %1$s seguido pelo PIN</string>
<string name="smscommunicator_otp_pin">PIN obrigatório adicional no token final</string>
@ -900,4 +900,18 @@
<string name="cannula">Cânula</string>
<string name="userentry">Entrada de Utilizador</string>
<string name="common_values">Utilize valores da sua maior refeição que normalmente come\n</string>
<string name="summary_email_for_crash_report">Este endereço de email irá anexado aos relatórios de erros para que possamos entrar em contato consigo em casos urgentes. É opcional.</string>
<string name="email_address">Endereço de email</string>
<string name="privacy_settings">Definições de privacidade</string>
<string name="privacy_summary">Opcionalmente pode fornecer um endereço de e-mail se quiser ser notificado sobre os erros da app. Este não é um serviço automatizado. Será contactado por desenvolvedores em situações perigosas.</string>
<string name="profile_low_target">Perfil Alvo Baixo</string>
<string name="profile_high_target">Perfil Alvo Alto</string>
<string name="temp_target_low_target">Valor Alvo Temporário Inferior</string>
<string name="temp_target_high_target">Valor Alvo Temporário Superior</string>
<string name="temp_target_value">Valor Alvo Temporário</string>
<string name="profile_dia">Valor Perfil DIA</string>
<string name="profile_sensitivity_value">Valor Perfil Sensibilidade</string>
<string name="profile_max_daily_basal_value">Valor Perfil Basal Máxima</string>
<string name="current_basal_value">Valor Actual Basal</string>
<string name="profile_carbs_ratio_value">Valor Perfil Rácio Hidratos</string>
</resources>

View file

@ -194,7 +194,6 @@
<string name="smscommunicator_loophasbeenenabled">Bucla a fost activată</string>
<string name="smscommunicator_loopisenabled">Bucla este activată</string>
<string name="valuelimitedto">%1$.2f este limitată la %2$.2f</string>
<string name="valueoutofrange">Valoarea %1$s este mai mare decât limita stabilită</string>
<string name="smscommunicator_pumpconnectwithcode">Pentru a conecta pompa raspundeti cu codul %1$s</string>
<string name="smscommunicator_pumpconnectfail">Conectarea cu pompa a esuat</string>
<string name="smscommunicator_pumpdisconnectwithcode">Pentru a deconecta pompa timp de %1$d minute, răspundeți cu: %2$s</string>

View file

@ -194,7 +194,7 @@
<string name="smscommunicator_loophasbeenenabled">зцикл был активирован</string>
<string name="smscommunicator_loopisenabled">зцикл работает</string>
<string name="valuelimitedto">%1$.2f ограничено до %2$.2f</string>
<string name="valueoutofrange">Значение %1$s недопустимо</string>
<string name="valueoutofrange">»%1$s«за пределами жестких ограничений</string>
<string name="smscommunicator_pumpconnectwithcode">Чтобы подсоединить помпу ответьте кодом %1$s</string>
<string name="smscommunicator_pumpconnectfail">Ошибка подключения к помпе</string>
<string name="smscommunicator_pumpdisconnectwithcode">Для разъединения с помпой на %1$d мин ответьте кодом %2$s</string>
@ -906,4 +906,14 @@ Context | Edit Context</string>
<string name="email_address">Адрес электронной почты</string>
<string name="privacy_settings">Настройки конфиденцальности</string>
<string name="privacy_summary">Вы можете указать дополнительно адрес электронной почты, если хотите получать уведомления о сбоях приложения; что является не автоматизированной рассылкой, а способом связи с разработчиками в опасных ситуациях.</string>
<string name="profile_low_target">Нижнее целевое значение профиля</string>
<string name="profile_high_target">Верхнее целевое значение профиля</string>
<string name="temp_target_low_target">Нижнее значение временного целевого уровня</string>
<string name="temp_target_high_target">Верхнее значение временного целевого уровня</string>
<string name="temp_target_value">Временное целевое значение</string>
<string name="profile_dia">Значение длительности действия инсулина DIA в профиле</string>
<string name="profile_sensitivity_value">Значение чувствительности в профиле</string>
<string name="profile_max_daily_basal_value">Максимальное значение базала в профиле</string>
<string name="current_basal_value">Текущее значение базала</string>
<string name="profile_carbs_ratio_value">Коэффициент углеводов в профиле</string>
</resources>

View file

@ -194,7 +194,6 @@
<string name="smscommunicator_loophasbeenenabled">Uzavretý okruh bol aktivovaný</string>
<string name="smscommunicator_loopisenabled">Uzavretý okruh je aktivovaný</string>
<string name="valuelimitedto">%1$.2f obmedzené na %2$.2f</string>
<string name="valueoutofrange">Hodnota %1$s je mimo prednastavený rozsah</string>
<string name="smscommunicator_pumpconnectwithcode">Ak chcete pripojiť pumpu, odpovedzte pomocou SMS s kódom %1$s</string>
<string name="smscommunicator_pumpconnectfail">Pripojenie k pumpe zlyhalo</string>
<string name="smscommunicator_pumpdisconnectwithcode">Ak chcete odpojiť pumpu na %1$d minút, odpovedzte pomocou SMS s kódom %2$s</string>
@ -900,4 +899,8 @@
<string name="cannula">Kanyla</string>
<string name="userentry">Vstup používateľa</string>
<string name="common_values">Použite hodnoty pre najväčšie jedlo, aké obvykle jete\n</string>
<string name="summary_email_for_crash_report">Táto e-mailová adresa bude pripojená ku správam o zlyhaniach, aby sme vás mohli kontaktovať v naliehavých prípadoch. Je to dobrovoľné.</string>
<string name="email_address">Emailová adresa</string>
<string name="privacy_settings">Nastavenia súkromia</string>
<string name="privacy_summary">Pokiaľ chcete byť upozornení na zlyhanie aplikácie, môžete zadať voliteľne e-mailovú adresu. Toto nie je automatizovaná služba. Vývojári vás budú kontaktovať v nebezpečných situáciách.</string>
</resources>

View file

@ -8,6 +8,7 @@
<string name="dia_meaningisequaltodiapump">Om du tycker att värdet för DIA som du använde i din pump före AndroidAPS fungerade väl, behöver du inte ändra det här när du börjar looping.</string>
<string name="dia_valuemustbedetermined">Du bör själv fastställa det lämpliga värdet för DIA.</string>
<string name="hypott_label">Hypo tempmål</string>
<string name="hypott_whenhypott">Vad är huvudskälet till att ange ett hypo tempmål?</string>
<string name="hypott_wrongbasal">För att korrigera känningar som orsakas av felaktiga basalinställningar.</string>
<string name="hypott_preventoversmb">För att förhindra att AndroidAPS överkorrigerar för de snabbverkande kolhydraterna som används för att behandla en insulinkänning.</string>
<string name="hypott_exercise">För att korrigera för en känning om ett resultat av motion.</string>
@ -40,12 +41,14 @@
<string name="noisycgm_label">Brusiga CGM-värden</string>
<string name="noisycgm_whattodo">Vad bör göras om CGM-datat är brusigt?</string>
<string name="noisycgm_nothing">Gör inget-AndroidAPS tar hand om det.</string>
<string name="noisycgm_pause">Inaktivera closed loop-läge för att undvika över- eller underdosering.</string>
<string name="noisycgm_replacesensor">Byt ut brusiga eller felaktiga sensorer.</string>
<string name="noisycgm_checksmoothing">Kontrollera att din CGM-app ger utjämnade data.</string>
<string name="noisycgm_hint1">https://androidaps.readthedocs.io/en/latest/EN/Usage/Smoothing-Blood-Glucose-Data-in-xDrip.html#smoothing-blood-glucose-data</string>
<string name="exerciseprofile_label">Träning och profiler</string>
<string name="exerciseprofile_whattodo">Hur kan du använda profiler för att bäst hjälpa systemet att hantera aerobisk träning?</string>
<string name="exerciseprofile_switchprofilebelow100">Gör ett profilbyte till mindre än 100%.</string>
<string name="exerciseprofile_switchprofileabove100">Gör ett profilbyte till mer än 100%.</string>
<string name="exerciseprofile_leaveat100">Lämna profilen på 100%.</string>
<string name="exerciseprofile_suspendloop">Pausa loopen.</string>
<string name="exerciseprofile_hint1">https://androidaps.readthedocs.io/en/latest/EN/Usage/temptarget.html#activity-temp-target</string>

View file

@ -195,7 +195,7 @@ Eversense-appen.</string>
<string name="smscommunicator_loophasbeenenabled">Loop aktiverad</string>
<string name="smscommunicator_loopisenabled">Loop är aktiverad</string>
<string name="valuelimitedto">%1$.2f begränsat till %2$.2f</string>
<string name="valueoutofrange">Värdet %1$s är utanför hård begränsning</string>
<string name="valueoutofrange">»%1$s« är utanför de hårda gränserna</string>
<string name="smscommunicator_pumpconnectwithcode">För att ansluta pumpen, svara med kod %1$s</string>
<string name="smscommunicator_pumpconnectfail">Anslutning till pump misslyckades</string>
<string name="smscommunicator_pumpdisconnectwithcode">För att koppla från pumpen i %1$d minuter, svara med kod %2$s</string>
@ -398,6 +398,7 @@ Eversense-appen.</string>
<string name="basal_shortname">Bas</string>
<string name="deviation_shortname">Dev</string>
<string name="activity_shortname">Akt</string>
<string name="bgi_shortname">-BGI</string>
<string name="abs_insulin_shortname">Abs</string>
<string name="devslope_shortname">Devslope</string>
<string name="nav_about">Om</string>
@ -471,6 +472,7 @@ Eversense-appen.</string>
<string name="activity_target">Mål vid träning</string>
<string name="hypo_duration">Hypo [min]</string>
<string name="hypo_target">Mål vid Hypo</string>
<string name="reuse_profile_pct_hours">Återanvänd %1$d%% %2$dtim</string>
<string name="wearcontrol_title">Kontrollera från klockan</string>
<string name="wearcontrol_summary">Sätt temp målvärde och ange behandlingar från klockan.</string>
<string name="food">Matdatabas</string>
@ -568,6 +570,7 @@ Eversense-appen.</string>
<string name="ns_autobackfill_summary">Hämta saknad BG-data från Nightscout</string>
<string name="loop_smbsetbypump_label">SMB satt i pump</string>
<string name="overview_show_activity">Insulinaktivitet (5m)</string>
<string name="overview_show_bgi">Blodglukospåverkan</string>
<string name="overview_show_sensitivity">Känslighet (Sens)</string>
<string name="overview_show_deviations">Avvikelser (Dev)</string>
<string name="overview_show_cob">Aktiva KH (COB)</string>
@ -892,4 +895,24 @@ Eversense-appen.</string>
<string name="timetoeat">Dags att äta</string>
<string name="fabric_upload_disabled">Uppladdning av kraschloggar inaktiverad!</string>
<string name="graph_menu_divider_header">Graf</string>
<string name="chart_menu">Diagrammeny</string>
<string name="clear_filter">Rensa filter</string>
<string name="trend_arrow">Trendpil</string>
<string name="cannula">Kanyl</string>
<string name="userentry">Angivet av användare</string>
<string name="common_values">Använd värden för den största måltiden som du vanligen äter\n</string>
<string name="summary_email_for_crash_report">Den här mejladressen kommer att bifogas till kraschrapporter så att vi kan kontakta dig i brådskande fall. Det är frivilligt.</string>
<string name="email_address">E-postadress</string>
<string name="privacy_settings">Sekretessinställningar</string>
<string name="privacy_summary">Du kan ange valfri e-postadress om du vill få meddelanden om appkrascher. Det här är ingen automatiserad tjänst. Du kommer att kontaktas av utvecklare i farliga situationer.</string>
<string name="profile_low_target">Nedre målvärde för profilen</string>
<string name="profile_high_target">Övre målvärde för profilen</string>
<string name="temp_target_low_target">Nedre värde för temp mål</string>
<string name="temp_target_high_target">Övre värde för temp mål</string>
<string name="temp_target_value">Temp målvärde</string>
<string name="profile_dia">Profilens DIA</string>
<string name="profile_sensitivity_value">Profilens insulinkänslighetsvärde</string>
<string name="profile_max_daily_basal_value">Maximal basaldos för profil</string>
<string name="current_basal_value">Nuvarande basaldos</string>
<string name="profile_carbs_ratio_value">Profilens KH-kvot</string>
</resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- <string name="fi_lang" translatable="false">Finnish</string> -->
<!-- <string name="he_lang" translatable="false">Hebrew</string> -->
<!-- <string name="ja_lang" translatable="false">Japanese</string> -->
<!-- SMS Communicator & OTP Authenticator -->
</resources>

View file

@ -152,7 +152,6 @@
<string name="smscommunicator_loophasbeenenabled">闭环已经被启用</string>
<string name="smscommunicator_loopisenabled">闭环被启用</string>
<string name="valuelimitedto">%1$.2f 超过 %2$.2f的限制</string>
<string name="valueoutofrange">值 %1$s 超过了硬限制</string>
<string name="smscommunicator_remotecommandnotallowed">远程命令没有被允许</string>
<string name="smscommunicator_remotebolusnotallowed">远程大剂量不可用。请稍后再试。</string>
<string name="smscommunicator_profilereplywithcode">要切换配置文件到 %1$s %2$d%% 请回复代码 %3$s</string>

View file

@ -23,6 +23,7 @@ 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.general.nsclient.UploadQueue
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage
@ -42,8 +43,6 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.anyString
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner
import java.util.*
@ -138,15 +137,18 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
constraintChecker = ConstraintChecker(activePlugin)
val glucoseStatusProvider = GlucoseStatusProvider(aapsLogger = aapsLogger, iobCobCalculatorPlugin = iobCobCalculatorPlugin)
danaPump = DanaPump(aapsLogger, sp, injector)
hardLimits = HardLimits(aapsLogger, rxBus, sp, resourceHelper, context, nsUpload)
objectivesPlugin = ObjectivesPlugin(injector, aapsLogger, resourceHelper, activePlugin, sp, Config(), uel)
comboPlugin = ComboPlugin(injector, aapsLogger, rxBus, resourceHelper, profileFunction, treatmentsInterface, sp, commandQueue, context, databaseHelper)
danaRPlugin = DanaRPlugin(injector, aapsLogger, aapsSchedulers, rxBus, context, resourceHelper, constraintChecker, activePlugin, sp, commandQueue, danaPump, dateUtil, fabricPrivacy)
danaRSPlugin = DanaRSPlugin(injector, aapsLogger, aapsSchedulers, rxBus, context, resourceHelper, constraintChecker, profileFunction, activePluginProvider, sp, commandQueue, danaPump, detailedBolusInfoStorage, fabricPrivacy, dateUtil)
insightPlugin = LocalInsightPlugin(injector, aapsLogger, rxBus, resourceHelper, treatmentsInterface, sp, commandQueue, profileFunction, nsUpload, context, uploadQueue, Config(), dateUtil, databaseHelper)
openAPSSMBPlugin = OpenAPSSMBPlugin(injector, aapsLogger, rxBus, constraintChecker, resourceHelper, profileFunction, context, activePlugin, treatmentsInterface, iobCobCalculatorPlugin, hardLimits, profiler, sp, dateUtil, repository)
openAPSAMAPlugin = OpenAPSAMAPlugin(injector, aapsLogger, rxBus, constraintChecker, resourceHelper, profileFunction, context, activePlugin, treatmentsInterface, iobCobCalculatorPlugin, hardLimits, profiler, fabricPrivacy, dateUtil, repository)
insightPlugin = LocalInsightPlugin(injector, aapsLogger, rxBus, resourceHelper, treatmentsInterface, sp, commandQueue, profileFunction, nsUpload, context, uploadQueue, Config(), dateUtil, databaseHelper, repository)
openAPSSMBPlugin = OpenAPSSMBPlugin(injector, aapsLogger, rxBus, constraintChecker, resourceHelper, profileFunction, context, activePlugin, treatmentsInterface, iobCobCalculatorPlugin, hardLimits, profiler, sp, dateUtil, repository, glucoseStatusProvider)
openAPSAMAPlugin = OpenAPSAMAPlugin(injector, aapsLogger, rxBus, constraintChecker, resourceHelper, profileFunction, context, activePlugin, treatmentsInterface, iobCobCalculatorPlugin, hardLimits, profiler, fabricPrivacy, dateUtil, repository, glucoseStatusProvider)
safetyPlugin = SafetyPlugin(injector, aapsLogger, resourceHelper, sp, rxBus, constraintChecker, openAPSAMAPlugin, openAPSSMBPlugin, sensitivityOref1Plugin, activePlugin, hardLimits, BuildHelper(Config(), loggerUtils), treatmentsInterface, Config())
val constraintsPluginsList = ArrayList<PluginBase>()
constraintsPluginsList.add(safetyPlugin)
@ -184,7 +186,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
Assert.assertEquals(false, c.value())
`when`(sp.getString(R.string.key_aps_mode, "open")).thenReturn("open")
c = constraintChecker.isClosedLoopAllowed()
Assert.assertTrue(c.reasonList[0].toString().contains("Closed loop mode disabled in preferences")) // Safety & Objectives
Assert.assertTrue(c.reasonList[0].contains("Closed loop mode disabled in preferences")) // Safety & Objectives
// Assert.assertEquals(3, c.reasonList.size) // 2x Safety & Objectives
Assert.assertEquals(false, c.value())
}

View file

@ -7,7 +7,12 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
@ -15,6 +20,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorP
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -30,7 +36,7 @@ import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class)
@PrepareForTest(
ConstraintChecker::class, VirtualPumpPlugin::class, FabricPrivacy::class, ReceiverStatusStore::class,
IobCobCalculatorPlugin::class)
IobCobCalculatorPlugin::class, AppRepository::class)
class LoopPluginTest : TestBase() {
@Mock lateinit var sp: SP
@ -48,14 +54,15 @@ class LoopPluginTest : TestBase() {
@Mock lateinit var receiverStatusStore: ReceiverStatusStore
@Mock lateinit var nsUpload: NSUpload
@Mock lateinit var notificationManager: NotificationManager
@Mock lateinit var databaseHelper: DatabaseHelperInterface
@Mock lateinit var repository: AppRepository
@Mock lateinit var dateUtil: DateUtil
private lateinit var loopPlugin: LoopPlugin
val injector = HasAndroidInjector { AndroidInjector { } }
@Before fun prepareMock() {
loopPlugin = LoopPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, Config(), constraintChecker, resourceHelper, profileFunction, context, commandQueue, activePlugin, treatmentsPlugin, virtualPumpPlugin, iobCobCalculatorPlugin, receiverStatusStore, fabricPrivacy, nsUpload, databaseHelper)
loopPlugin = LoopPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, Config(), constraintChecker, resourceHelper, profileFunction, context, commandQueue, activePlugin, treatmentsPlugin, virtualPumpPlugin, iobCobCalculatorPlugin, receiverStatusStore, fabricPrivacy, nsUpload, dateUtil, repository)
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
`when`(context.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(notificationManager)
}

View file

@ -27,7 +27,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
@ -91,10 +91,6 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
it.resourceHelper = resourceHelper
it.otp = otp
}
if (it is GlucoseStatus) {
it.aapsLogger = aapsLogger
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
}
}
}
@ -121,8 +117,9 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
repository.runTransactionForResult(anyObject<InsertTemporaryTargetAndCancelCurrentTransaction>())
).thenReturn(Single.just(InsertTemporaryTargetAndCancelCurrentTransaction.TransactionResult().apply {
}))
val glucoseStatusProvider = GlucoseStatusProvider(aapsLogger = aapsLogger, iobCobCalculatorPlugin = iobCobCalculatorPlugin)
smsCommunicatorPlugin = SmsCommunicatorPlugin(injector, aapsLogger, resourceHelper, aapsSchedulers, sp, constraintChecker, rxBus, profileFunction, fabricPrivacy, activePlugin, commandQueue, loopPlugin, iobCobCalculatorPlugin, xdripCalibrations, otp, Config(), DateUtil(context), uel, nsUpload, repository)
smsCommunicatorPlugin = SmsCommunicatorPlugin(injector, aapsLogger, resourceHelper, aapsSchedulers, sp, constraintChecker, rxBus, profileFunction, fabricPrivacy, activePlugin, commandQueue, loopPlugin, iobCobCalculatorPlugin, xdripCalibrations, otp, Config(), DateUtil(context), uel, nsUpload, glucoseStatusProvider, repository)
smsCommunicatorPlugin.setPluginEnabled(PluginType.GENERAL, true)
Mockito.doAnswer { invocation: InvocationOnMock ->
val callback = invocation.getArgument<Callback>(1)

View file

@ -16,6 +16,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
@ -59,10 +60,7 @@ class BolusWizardTest : TestBase() {
it.commandQueue = commandQueue
it.loopPlugin = loopPlugin
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
}
if (it is GlucoseStatus) {
it.aapsLogger = aapsLogger
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
it.glucoseStatusProvider = GlucoseStatusProvider(aapsLogger = aapsLogger, iobCobCalculatorPlugin = iobCobCalculatorPlugin)
}
}
}

View file

@ -20,6 +20,7 @@ import info.nightscout.androidaps.plugins.general.automation.dialogs.ChooseTrigg
import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerChanged
import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerClone
import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerRemove
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.services.LastLocationDataContainer
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -39,6 +40,7 @@ abstract class Trigger(val injector: HasAndroidInjector) {
@Inject lateinit var treatmentsInterface: TreatmentsInterface
@Inject lateinit var activePlugin: ActivePluginProvider
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorInterface
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
init {
injector.androidInjector().inject(this)

View file

@ -46,7 +46,7 @@ class TriggerBg(injector: HasAndroidInjector) : Trigger(injector) {
}
override fun shouldRun(): Boolean {
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (glucoseStatus == null && comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true

View file

@ -64,7 +64,7 @@ class TriggerDelta(injector: HasAndroidInjector) : Trigger(injector) {
}
override fun shouldRun(): Boolean {
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
?: return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
true

View file

@ -5,6 +5,7 @@ import com.google.common.base.Optional
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.automation.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.automation.elements.ComparatorExists
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder
@ -36,11 +37,11 @@ class TriggerTempTarget(injector: HasAndroidInjector) : Trigger(injector) {
override fun shouldRun(): Boolean {
val tt = repository.getTemporaryTargetActiveAt(dateUtil._now()).blockingGet()
if (tt == null && comparator.value == ComparatorExists.Compare.NOT_EXISTS) {
if (tt is ValueWrapper.Absent && comparator.value == ComparatorExists.Compare.NOT_EXISTS) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true
}
if (tt != null && comparator.value == ComparatorExists.Compare.EXISTS) {
if (tt is ValueWrapper.Existing && comparator.value == ComparatorExists.Compare.EXISTS) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true
}

View file

@ -7,6 +7,7 @@
<string name="automation_missing_trigger">Prosím, zadajte aspoň jednu podmienku.</string>
<string name="automation_missing_action">Prosím, zadajte aspoň jednu akciu.</string>
<string name="alarm_message">Výstraha: %1$s</string>
<string name="alarm_short">Alarm:</string>
<string name="message_short">Spr:</string>
<string name="alreadyenabled">Už aktivované</string>
<string name="alreadydisabled">Už deaktivované</string>
@ -88,6 +89,7 @@
<string name="glucose_u">Glykémia [%1$s]:</string>
<string name="lastboluslabel">Od posledného bolusu</string>
<string name="lastboluscompared">Čas posledného bolusu: pred %1$s %2$s min </string>
<string name="triggercoblabel">COB</string>
<string name="cobcompared">COB %1$s %2$.0f</string>
<string name="iob_u">IOB [JI]:</string>
<string name="distance_short">Vzdial. [m]:</string>

View file

@ -7,6 +7,7 @@
<string name="automation_missing_trigger">Specificera åtminstone en utlösare.</string>
<string name="automation_missing_action">Specificera åtminstone en åtgärd.</string>
<string name="alarm_message">Larm: %1$s</string>
<string name="alarm_short">Larm:</string>
<string name="message_short">Medd:</string>
<string name="alreadyenabled">Redan aktiverad</string>
<string name="alreadydisabled">Redan inaktiverad</string>
@ -88,6 +89,7 @@
<string name="glucose_u">BG [%1$s]:</string>
<string name="lastboluslabel">Senaste bolus</string>
<string name="lastboluscompared">Senaste bolus %1$s %2$s min sedan</string>
<string name="triggercoblabel">COB</string>
<string name="cobcompared">COB %1$s %2$.0f</string>
<string name="iob_u">IOB [U]:</string>
<string name="distance_short">Dist [m]:</string>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -15,6 +15,7 @@ import info.nightscout.androidaps.plugins.general.automation.elements.InputBg
import info.nightscout.androidaps.plugins.general.automation.elements.InputTempTarget
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.services.LastLocationDataContainer
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -57,6 +58,7 @@ open class TriggerTestBase : TestBaseWithProfile() {
it.treatmentsInterface = treatmentsInterface
it.activePlugin = activePlugin
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
it.glucoseStatusProvider = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin)
}
if (it is TriggerBg) {
it.profileFunction = profileFunction
@ -83,10 +85,6 @@ open class TriggerTestBase : TestBaseWithProfile() {
if (it is InputTempTarget) {
it.profileFunction = profileFunction
}
if (it is GlucoseStatus) {
it.aapsLogger = aapsLogger
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
}
if (it is StaticLabel) {
it.resourceHelper = resourceHelper
}

View file

@ -17,4 +17,5 @@ android {
dependencies {
implementation project(':core')
implementation project(':database')
}

View file

@ -6,6 +6,7 @@ import android.os.SystemClock;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.joda.time.DateTime;
import org.json.JSONObject;
import java.util.ArrayList;
@ -24,7 +25,7 @@ import info.nightscout.androidaps.combo.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.database.entities.TherapyEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TDD;
import info.nightscout.androidaps.db.TemporaryBasal;
@ -996,8 +997,8 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
double pumpBasalRate = state.tbrActive
? Math.round(state.basalRate * 100 / state.tbrPercent * 100) / 100d
: state.basalRate;
int pumpHour = new Date(state.pumpTime).getHours();
int phoneHour = new Date().getHours();
int pumpHour = new DateTime(state.pumpTime).getHourOfDay();
int phoneHour = DateTime.now().getHourOfDay();
if (pumpHour != phoneHour) {
// only check if clocks are close
return;
@ -1157,7 +1158,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
dbi.pumpId = dbi.date;
dbi.source = Source.PUMP;
dbi.insulin = pumpBolus.amount;
dbi.eventType = CareportalEvent.CORRECTIONBOLUS;
dbi.eventType = TherapyEvent.Type.CORRECTION_BOLUS.getText();
if (treatmentsPlugin.addToHistoryTreatment(dbi, true)) {
updated = true;
}

View file

@ -3,6 +3,7 @@
<string name="description_pump_combo">Ovládač pumpy pre Accu-Check Combo, vyžaduje nainštalovanú aplikáciu Ruffy</string>
<string name="combo_programming_bolus">Programovanie pumpy pre bolus</string>
<string name="combo_pump_state_label">Stav</string>
<string name="combo_pump_activity_label">Aktivita</string>
<string name="combo_no_pump_connection">Žiadne spojenie už %1$d min</string>
<string name="combo_tbr_remaining">%1$d%% (%2$d min zostáva)</string>
<string name="combo_pump_state_initializing">Inicializácia</string>

View file

@ -3,6 +3,7 @@
<string name="description_pump_combo">Pumpintegration för Accu-Chek Combo. Kräver att Ruffy är installerat</string>
<string name="combo_programming_bolus">Programmerar bolus i pump</string>
<string name="combo_pump_state_label">Läge</string>
<string name="combo_pump_activity_label">Insulinaktivitet (5m)</string>
<string name="combo_no_pump_connection">Ingen anslutning på %1$d min</string>
<string name="combo_tbr_remaining">%1$d%% (%2$d min återstår)</string>
<string name="combo_pump_state_initializing">Initierar</string>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -5,25 +5,32 @@ import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.data.GlucoseValueDataPoint
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.db.*
import info.nightscout.androidaps.data.TherapyEventDataPoint
import info.nightscout.androidaps.db.ExtendedBolus
import info.nightscout.androidaps.db.ProfileSwitch
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(): Profile
@ContributesAndroidInjector abstract fun profileStoreInjector(): ProfileStore
@ContributesAndroidInjector abstract fun glucoseValueDataPointInjector(): GlucoseValueDataPoint
@ContributesAndroidInjector abstract fun treatmentInjector(): Treatment
@ContributesAndroidInjector abstract fun profileSwitchInjector(): ProfileSwitch
@ContributesAndroidInjector abstract fun temporaryBasalInjector(): TemporaryBasal
@ContributesAndroidInjector abstract fun careportalEventInjector(): CareportalEvent
@ContributesAndroidInjector abstract fun extendedBolusInjector(): ExtendedBolus
@ContributesAndroidInjector abstract fun glucoseValueDataPointInjector(): GlucoseValueDataPoint
@ContributesAndroidInjector abstract fun therapyEventDataPointInjector(): TherapyEventDataPoint
}

View file

@ -6,7 +6,7 @@ import org.json.JSONObject;
import java.util.Date;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.database.entities.TherapyEvent;
import info.nightscout.androidaps.db.Source;
/**
@ -16,7 +16,7 @@ import info.nightscout.androidaps.db.Source;
public class DetailedBolusInfo {
public long date = System.currentTimeMillis();
public long lastKnownBolusTime;
public String eventType = CareportalEvent.MEALBOLUS;
public String eventType = TherapyEvent.Type.MEAL_BOLUS.getText();
public double insulin = 0;
public double carbs = 0;
public int source = Source.NONE;

View file

@ -0,0 +1,104 @@
package info.nightscout.androidaps.data
import android.graphics.Color
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.interfaces.Interval
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.Translator
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
class TherapyEventDataPoint @Inject constructor(
val injector: HasAndroidInjector,
val data: TherapyEvent
) : DataPointWithLabelInterface, Interval {
@Inject lateinit var defaultValueHelper: DefaultValueHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var translator: Translator
private var yValue = 0.0
init {
injector.androidInjector().inject(this)
}
override fun getX(): Double {
return data.timestamp.toDouble()
}
override fun getY(): Double {
val units = profileFunction.getUnits()
if (data.type == TherapyEvent.Type.NS_MBG) return Profile.fromMgdlToUnits(data.glucose!!, units)
if (data.glucose != null && data.glucose != 0.0) {
var mmol = 0.0
var mgdl = 0.0
if (units == Constants.MGDL) {
mgdl = data.glucose!!
mmol = data.glucose!! * Constants.MGDL_TO_MMOLL
}
if (units == Constants.MMOL) {
mmol = data.glucose!!
mgdl = data.glucose!! * Constants.MMOLL_TO_MGDL
}
return Profile.toUnits(mgdl, mmol, units)
}
return yValue
}
override fun setY(y: Double) {
yValue = y
}
override fun getLabel(): String? =
if (data.note != null) data.note
else translator.translate(data.type.text)
override fun getDuration(): Long = end() - start()
override fun getShape(): PointsWithLabelGraphSeries.Shape =
when {
data.type == TherapyEvent.Type.NS_MBG -> PointsWithLabelGraphSeries.Shape.MBG
data.type == TherapyEvent.Type.FINGER_STICK_BG_VALUE -> PointsWithLabelGraphSeries.Shape.BGCHECK
data.type == TherapyEvent.Type.ANNOUNCEMENT -> PointsWithLabelGraphSeries.Shape.ANNOUNCEMENT
data.type == TherapyEvent.Type.APS_OFFLINE -> PointsWithLabelGraphSeries.Shape.OPENAPSOFFLINE
data.type == TherapyEvent.Type.EXERCISE -> PointsWithLabelGraphSeries.Shape.EXERCISE
duration > 0 -> PointsWithLabelGraphSeries.Shape.GENERALWITHDURATION
else -> PointsWithLabelGraphSeries.Shape.GENERAL
}
override fun getSize(): Float = if (resourceHelper.gb(R.bool.isTablet)) 12.0f else 10.0f
override fun getColor(): Int =
when (data.type) {
TherapyEvent.Type.ANNOUNCEMENT -> resourceHelper.gc(R.color.notificationAnnouncement)
TherapyEvent.Type.NS_MBG -> Color.RED
TherapyEvent.Type.FINGER_STICK_BG_VALUE -> Color.RED
TherapyEvent.Type.EXERCISE -> Color.BLUE
TherapyEvent.Type.APS_OFFLINE -> Color.GRAY and -0x7f000001
else -> Color.GRAY
}
// Interval interface
private var cutEnd: Long? = null
override fun durationInMsec(): Long = data.duration
override fun start(): Long = data.timestamp
override fun originalEnd(): Long = data.timestamp + durationInMsec()
override fun end(): Long = cutEnd ?: originalEnd()
override fun cutEndTo(end: Long) {
cutEnd = end
}
override fun match(time: Long): Boolean = start() <= time && end() >= time
override fun before(time: Long): Boolean = end() < time
override fun after(time: Long): Boolean = start() > time
override val isInProgress: Boolean get() = match(System.currentTimeMillis())
override val isEndingEvent: Boolean get() = durationInMsec() == 0L
override val isValid: Boolean get() = data.type == TherapyEvent.Type.APS_OFFLINE
}

View file

@ -1,354 +0,0 @@
package info.nightscout.androidaps.db;
import android.graphics.Color;
import androidx.annotation.NonNull;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.core.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.Interval;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.interfaces.ProfileFunction;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.Translator;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
@DatabaseTable(tableName = "CareportalEvents")
public class CareportalEvent implements DataPointWithLabelInterface, Interval {
@Inject ProfileFunction profileFunction;
@Inject ResourceHelper resourceHelper;
@Inject AAPSLogger aapsLogger;
@Inject Translator translator;
@Inject DateUtil dateUtil;
@DatabaseField(id = true)
public long date;
@DatabaseField
public boolean isValid = true;
@DatabaseField
public int source = Source.NONE;
@DatabaseField
public String _id;
@DatabaseField
public String eventType;
@DatabaseField
public String json;
public static final String CARBCORRECTION = "Carb Correction";
public static final String BOLUSWIZARD = "Bolus Wizard";
public static final String CORRECTIONBOLUS = "Correction Bolus";
public static final String MEALBOLUS = "Meal Bolus";
public static final String COMBOBOLUS = "Combo Bolus";
public static final String TEMPBASAL = "Temp Basal";
public static final String TEMPORARYTARGET = "Temporary Target";
public static final String PROFILESWITCH = "Profile Switch";
public static final String SITECHANGE = "Site Change";
public static final String INSULINCHANGE = "Insulin Change";
public static final String SENSORCHANGE = "Sensor Change";
public static final String PUMPBATTERYCHANGE = "Pump Battery Change";
public static final String BGCHECK = "BG Check";
public static final String ANNOUNCEMENT = "Announcement";
public static final String NOTE = "Note";
public static final String QUESTION = "Question";
public static final String EXERCISE = "Exercise";
public static final String OPENAPSOFFLINE = "OpenAPS Offline";
public static final String NONE = "<none>";
public static final String MBG = "Mbg"; // comming from entries
// found in CareDialog.kt file
public static final String FINGER = "Finger";
public static final String SENSOR = "Sensor";
public static final String MANUAL = "Manual";
// found in Translator.kt
public static final String SNACKBOLUS = "Snack Bolus";
public static final String SENSORSTART = "Sensor Start";
public static final String TEMPBASALSTART = "Temp Basal Start";
public static final String TEMPBASALEND = "Temp Basal End";
public static final String TEMPBASALCANCEL = "Temporary Target Cancel";
@Deprecated
public CareportalEvent() {
StaticInjector.Companion.getInstance().androidInjector().inject(this);
}
public CareportalEvent(HasAndroidInjector injector) {
injector.androidInjector().inject(this);
}
public CareportalEvent(NSMbg mbg) {
this();
date = mbg.date;
eventType = MBG;
json = mbg.json;
}
public long getMillisecondsFromStart() {
return System.currentTimeMillis() - date;
}
private double getHoursFromStart() {
return (System.currentTimeMillis() - date) / (60 * 60 * 1000.0);
}
public String age(boolean useShortText, ResourceHelper resourceHelper) {
Map<TimeUnit, Long> diff = DateUtil.computeDiff(date, System.currentTimeMillis());
String days = " " + resourceHelper.gs(R.string.days) + " ";
String hours = " " + resourceHelper.gs(R.string.hours) + " ";
if (useShortText) {
days = resourceHelper.gs(R.string.shortday);
hours = resourceHelper.gs(R.string.shorthour);
}
return diff.get(TimeUnit.DAYS) + days + diff.get(TimeUnit.HOURS) + hours;
}
public boolean isOlderThan(double hours) {
return getHoursFromStart() > hours;
}
@Override @NonNull
public String toString() {
return "CareportalEvent{" +
"date= " + date +
", date= " + dateUtil.dateAndTimeString(date) +
", isValid= " + isValid +
", _id= " + _id +
", eventType= " + eventType +
", json= " + json +
"}";
}
public boolean isEvent5minBack(List<CareportalEvent> list, long time) {
for (int i = 0; i < list.size(); i++) {
CareportalEvent event = list.get(i);
if (event.date <= time && event.date > (time - T.mins(5).msecs())) {
aapsLogger.debug(LTag.DATABASE, "Found event for time: " + dateUtil.dateAndTimeString(time) + " " + event.toString());
return true;
}
}
return false;
}
// -------- DataPointWithLabelInterface -------
@Override
public double getX() {
return date;
}
private double yValue = 0;
@Override
public double getY() {
String units = profileFunction.getUnits();
if (eventType.equals(MBG)) {
double mbg = 0d;
try {
JSONObject object = new JSONObject(json);
mbg = object.getDouble("mgdl");
} catch (JSONException e) {
aapsLogger.error("Unhandled exception", e);
}
return Profile.fromMgdlToUnits(mbg, units);
}
double glucose = 0d;
try {
JSONObject object = new JSONObject(json);
if (object.has("glucose")) {
glucose = object.getDouble("glucose");
units = object.getString("units");
}
} catch (JSONException e) {
aapsLogger.error("Unhandled exception", e);
}
if (glucose != 0d) {
double mmol = 0d;
double mgdl = 0;
if (units.equals(Constants.MGDL)) {
mgdl = glucose;
mmol = glucose * Constants.MGDL_TO_MMOLL;
}
if (units.equals(Constants.MMOL)) {
mmol = glucose;
mgdl = glucose * Constants.MMOLL_TO_MGDL;
}
return Profile.toUnits(mgdl, mmol, units);
}
return yValue;
}
@Override
public void setY(double y) {
yValue = y;
}
@Override
public String getLabel() {
try {
JSONObject object = new JSONObject(json);
if (object.has("notes"))
return StringUtils.abbreviate(object.getString("notes"), 40);
} catch (JSONException e) {
aapsLogger.error("Unhandled exception", e);
}
return translator.translate(eventType);
}
public String getNotes() {
try {
JSONObject object = new JSONObject(json);
if (object.has("notes"))
return object.getString("notes");
} catch (JSONException e) {
aapsLogger.error("Unhandled exception", e);
}
return "";
}
@Override
public long getDuration() {
return end() - start();
}
@Override
public PointsWithLabelGraphSeries.Shape getShape() {
switch (eventType) {
case CareportalEvent.MBG:
return PointsWithLabelGraphSeries.Shape.MBG;
case CareportalEvent.BGCHECK:
return PointsWithLabelGraphSeries.Shape.BGCHECK;
case CareportalEvent.ANNOUNCEMENT:
return PointsWithLabelGraphSeries.Shape.ANNOUNCEMENT;
case CareportalEvent.OPENAPSOFFLINE:
return PointsWithLabelGraphSeries.Shape.OPENAPSOFFLINE;
case CareportalEvent.EXERCISE:
return PointsWithLabelGraphSeries.Shape.EXERCISE;
}
if (getDuration() > 0)
return PointsWithLabelGraphSeries.Shape.GENERALWITHDURATION;
return PointsWithLabelGraphSeries.Shape.GENERAL;
}
@Override
public float getSize() {
boolean isTablet = resourceHelper.gb(R.bool.isTablet);
return isTablet ? 12 : 10;
}
@Override
public int getColor() {
if (eventType.equals(ANNOUNCEMENT))
return resourceHelper.gc(R.color.notificationAnnouncement);
if (eventType.equals(MBG))
return Color.RED;
if (eventType.equals(BGCHECK))
return Color.RED;
if (eventType.equals(EXERCISE))
return Color.BLUE;
if (eventType.equals(OPENAPSOFFLINE))
return Color.GRAY & 0x80FFFFFF;
return Color.GRAY;
}
// Interval interface
private Long cuttedEnd = null;
@Override
public long durationInMsec() {
try {
JSONObject object = new JSONObject(json);
if (object.has("duration"))
return object.getInt("duration") * 60 * 1000L;
} catch (JSONException e) {
aapsLogger.error("Unhandled exception", e);
}
return 0;
}
@Override
public long start() {
return date;
}
@Override
public long originalEnd() {
return date + durationInMsec();
}
@Override
public long end() {
if (cuttedEnd != null)
return cuttedEnd;
return originalEnd();
}
@Override
public void cutEndTo(long end) {
cuttedEnd = end;
}
@Override
public boolean match(long time) {
if (start() <= time && end() >= time)
return true;
return false;
}
public boolean before(long time) {
if (end() < time)
return true;
return false;
}
public boolean after(long time) {
if (start() > time)
return true;
return false;
}
@Override
public boolean isInProgress() {
return match(System.currentTimeMillis());
}
@Override
public boolean isEndingEvent() {
return durationInMsec() == 0;
}
@Override
public boolean isValid() {
return eventType.equals(OPENAPSOFFLINE);
}
}

View file

@ -9,7 +9,6 @@ interface DatabaseHelperInterface {
fun resetDatabases()
fun createOrUpdate(careportalEvent: CareportalEvent)
fun createOrUpdate(extendedBolus: ExtendedBolus): Boolean
fun createOrUpdate(profileSwitch: ProfileSwitch)
fun createOrUpdate(record: DanaRHistoryRecord)
@ -26,7 +25,6 @@ interface DatabaseHelperInterface {
fun deleteDbRequest(id: String): Int
fun delete(tempBasal: TemporaryBasal)
fun delete(extendedBolus: ExtendedBolus)
fun delete(careportalEvent: CareportalEvent)
fun delete(profileSwitch: ProfileSwitch)
fun deleteDbRequestbyMongoId(action: String, _id: String)
fun getDbRequestIterator(): CloseableIterator<DbRequest>
@ -36,12 +34,6 @@ interface DatabaseHelperInterface {
fun findTempBasalByPumpId(id: Long): TemporaryBasal
fun getTemporaryBasalsDataFromTime(mills: Long, ascending: Boolean): List<TemporaryBasal>
fun getExtendedBolusDataFromTime(mills: Long, ascending: Boolean): List<ExtendedBolus>
fun getCareportalEventFromTimestamp(timestamp: Long): CareportalEvent?
fun getLastCareportalEvent(event: String): CareportalEvent?
fun getCareportalEventsFromTime(mills: Long, ascending: Boolean): List<CareportalEvent>
fun getCareportalEventsFromTime(mills: Long, type: String, ascending: Boolean): List<CareportalEvent>
fun getCareportalEvents(start: Long, end: Long, ascending: Boolean): List<CareportalEvent>
fun getCareportalEvents(ascending: Boolean): List<CareportalEvent>
fun getProfileSwitchEventsFromTime(from: Long, to: Long, ascending: Boolean): List<ProfileSwitch>
fun getProfileSwitchEventsFromTime(mills: Long, ascending: Boolean): List<ProfileSwitch>
fun getAllOmnipodHistoryRecordsFromTimestamp(timestamp: Long, ascending: Boolean): List<OmnipodHistoryRecord>
@ -49,23 +41,19 @@ interface DatabaseHelperInterface {
fun getTDDsForLastXDays(days: Int): List<TDD>
fun getProfileSwitchData(from: Long, ascending: Boolean): List<ProfileSwitch>
fun getExtendedBolusByPumpId(pumpId: Long): ExtendedBolus?
fun getAllCareportalEvents(): List<CareportalEvent>
fun getAllExtendedBoluses(): List<ExtendedBolus>
fun getAllProfileSwitches(): List<ProfileSwitch>
fun getAllTDDs(): List<TDD>
fun getAllTemporaryBasals(): List<TemporaryBasal>
fun getAllOHQueueItems(maxEntries: Long): List<OHQueueItem>
fun resetCareportalEvents()
fun resetProfileSwitch()
// old DB model
fun deleteTempBasalById(_id: String)
fun deleteExtendedBolusById(_id: String)
fun deleteCareportalEventById(_id: String)
fun deleteProfileSwitchById(_id: String)
fun createTempBasalFromJsonIfNotExists(json: JSONObject)
fun createExtendedBolusFromJsonIfNotExists(json: JSONObject)
fun createCareportalEventFromJsonIfNotExists(json: JSONObject)
fun createProfileSwitchFromJsonIfNotExists(activePluginProvider: ActivePluginProvider, nsUpload: NSUpload, trJson: JSONObject)
fun getInsightBolusID(pumpSerial: String, bolusID: Int, timestamp: Long): InsightBolusID?

View file

@ -20,13 +20,11 @@ import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.database.entities.GlucoseValue;
import info.nightscout.androidaps.database.entities.TemporaryTarget;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.database.entities.TherapyEvent;
import info.nightscout.androidaps.db.DbRequest;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
import info.nightscout.androidaps.interfaces.IobCobCalculatorInterface;
import info.nightscout.androidaps.interfaces.LoopInterface;
import info.nightscout.androidaps.interfaces.ProfileFunction;
@ -51,12 +49,10 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP;
@Singleton
public class NSUpload {
private final HasAndroidInjector injector;
private final AAPSLogger aapsLogger;
private final ResourceHelper resourceHelper;
private final SP sp;
private final UploadQueueInterface uploadQueue;
private final DatabaseHelperInterface databaseHelper;
private final RunningConfiguration runningConfiguration;
private final ProfileFunction profileFunction;
@ -64,29 +60,25 @@ public class NSUpload {
@Inject
public NSUpload(
HasAndroidInjector injector,
AAPSLogger aapsLogger,
ResourceHelper resourceHelper,
SP sp,
UploadQueueInterface uploadQueue,
RunningConfiguration runningConfiguration,
DatabaseHelperInterface databaseHelper,
ProfileFunction profileFunction
) {
this.injector = injector;
this.aapsLogger = aapsLogger;
this.resourceHelper = resourceHelper;
this.sp = sp;
this.uploadQueue = uploadQueue;
this.runningConfiguration = runningConfiguration;
this.databaseHelper = databaseHelper;
this.profileFunction = profileFunction;
}
public void uploadTempBasalStartAbsolute(TemporaryBasal temporaryBasal, Double originalExtendedAmount) {
try {
JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.TEMPBASAL);
data.put("eventType", TherapyEvent.Type.TEMPORARY_BASAL.getText());
data.put("duration", temporaryBasal.durationInMinutes);
data.put("absolute", temporaryBasal.absoluteRate);
data.put("rate", temporaryBasal.absoluteRate);
@ -118,7 +110,7 @@ public class NSUpload {
}
} else {
JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.TEMPBASAL);
data.put("eventType", TherapyEvent.Type.TEMPORARY_BASAL.getText());
data.put("duration", temporaryBasal.durationInMinutes);
data.put("percent", temporaryBasal.percentRate - 100);
if (profile != null)
@ -137,7 +129,7 @@ public class NSUpload {
public void uploadTempBasalEnd(long time, boolean isFakedTempBasal, long pumpId) {
try {
JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.TEMPBASAL);
data.put("eventType", TherapyEvent.Type.TEMPORARY_BASAL.getText());
data.put("created_at", DateUtil.toISOString(time));
data.put("enteredBy", "openaps://" + "AndroidAPS");
if (isFakedTempBasal)
@ -153,7 +145,7 @@ public class NSUpload {
public void uploadExtendedBolus(ExtendedBolus extendedBolus) {
try {
JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.COMBOBOLUS);
data.put("eventType", TherapyEvent.Type.COMBO_BOLUS.getText());
data.put("duration", extendedBolus.durationInMinutes);
data.put("splitNow", 0);
data.put("splitExt", 100);
@ -172,7 +164,7 @@ public class NSUpload {
public void uploadExtendedBolusEnd(long time, long pumpId) {
try {
JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.COMBOBOLUS);
data.put("eventType", TherapyEvent.Type.COMBO_BOLUS.getText());
data.put("duration", 0);
data.put("splitNow", 0);
data.put("splitExt", 100);
@ -293,7 +285,7 @@ public class NSUpload {
public void uploadTempTarget(TemporaryTarget tempTarget) {
try {
JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.TEMPORARYTARGET);
data.put("eventType", TherapyEvent.Type.TEMPORARY_TARGET.getText());
data.put("duration", T.msecs(tempTarget.getDuration()).mins());
data.put(ISVALID, tempTarget.isValid());
if (tempTarget.getLowTarget() > 0) {
@ -313,7 +305,7 @@ public class NSUpload {
public void updateTempTarget(TemporaryTarget tempTarget) {
try {
JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.TEMPORARYTARGET);
data.put("eventType", TherapyEvent.Type.TEMPORARY_TARGET.getText());
data.put("duration", T.msecs(tempTarget.getDuration()).mins());
data.put(ISVALID, tempTarget.isValid());
if (tempTarget.getLowTarget() > 0) {
@ -343,7 +335,7 @@ public class NSUpload {
private static JSONObject getJson(ProfileSwitch profileSwitch) throws JSONException {
JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.PROFILESWITCH);
data.put("eventType", TherapyEvent.Type.PROFILE_SWITCH.getText());
data.put("duration", profileSwitch.durationInMinutes);
data.put("profile", profileSwitch.getCustomizedName());
data.put("profileJson", profileSwitch.profileJson);
@ -382,21 +374,11 @@ public class NSUpload {
}
// TODO replace with seting isValid = false
public void removeCareportalEntryFromNS(String _id) {
uploadQueue.add(new DbRequest("dbRemove", "treatments", _id, System.currentTimeMillis()));
}
public void uploadOpenAPSOffline(CareportalEvent event) {
try {
JSONObject data = new JSONObject(event.json);
data.put("created_at", DateUtil.toISOString(event.date));
data.put("enteredBy", "openaps://" + "AndroidAPS");
uploadQueue.add(new DbRequest("dbAdd", "treatments", data, event.date));
} catch (JSONException e) {
aapsLogger.error("Unhandled exception", e);
}
}
public void uploadError(String error) {
uploadError(error, new Date());
}
@ -473,6 +455,7 @@ public class NSUpload {
data.put("eventType", careportalEvent);
data.put("created_at", DateUtil.toISOString(time));
data.put("enteredBy", sp.getString("careportal_enteredby", "AndroidAPS"));
data.put("units", profileFunction.getUnits());
if (notes != null) {
data.put("notes", notes);
}
@ -482,6 +465,23 @@ public class NSUpload {
uploadQueue.add(new DbRequest("dbAdd", "treatments", data, time));
}
public void uploadEvent(TherapyEvent event) {
JSONObject data = new JSONObject();
try {
data.put("eventType", event.getType().getText());
data.put("created_at", event.getTimestamp());
data.put("enteredBy", event.getEnteredBy());
if (event.getUnits() != null) data.put("units", event.getUnits());
if (event.getDuration() != 0) data.put("duration", T.msecs(event.getDuration()).mins());
if (event.getNote() != null) data.put("notes", event.getNote());
if (event.getGlucose() != null) data.put("glucose", event.getGlucose());
if (event.getGlucoseType() != null) data.put("glucoseType", event.getGlucoseType().getText());
} catch (JSONException e) {
aapsLogger.error("Unhandled exception", e);
}
uploadQueue.add(new DbRequest("dbAdd", "treatments", data, event.getTimestamp()));
}
public void removeFoodFromNS(String _id) {
try {
uploadQueue.add(new DbRequest("dbRemove", "food", _id, System.currentTimeMillis()));
@ -492,7 +492,7 @@ public class NSUpload {
}
public void createNSTreatment(JSONObject data, ProfileStore profileStore, ProfileFunction profileFunction, long eventTime) {
if (JsonHelper.safeGetString(data, "eventType", "").equals(CareportalEvent.PROFILESWITCH)) {
if (JsonHelper.safeGetString(data, "eventType", "").equals(TherapyEvent.Type.PROFILE_SWITCH.getText())) {
ProfileSwitch profileSwitch = profileFunction.prepareProfileSwitch(
profileStore,
JsonHelper.safeGetString(data, "profile"),
@ -513,27 +513,4 @@ public class NSUpload {
return _id.length() == 24;
}
public void generateCareportalEvent(String eventType, long time, String notes) {
CareportalEvent careportalEvent = new CareportalEvent(injector);
careportalEvent.source = Source.USER;
careportalEvent.date = time;
careportalEvent.json = generateJson(eventType, time, notes).toString();
careportalEvent.eventType = eventType;
databaseHelper.createOrUpdate(careportalEvent);
uploadEvent(eventType, time, notes);
}
private JSONObject generateJson(String careportalEvent, long time, String notes) {
JSONObject data = new JSONObject();
try {
data.put("eventType", careportalEvent);
data.put("created_at", DateUtil.toISOString(time));
data.put("mills", time);
data.put("enteredBy", sp.getString("careportal_enteredby", "AndroidAPS"));
if (!notes.isEmpty()) data.put("notes", notes);
} catch (JSONException ignored) {
}
return data;
}
}

View file

@ -2,25 +2,40 @@ package info.nightscout.androidaps.plugins.general.nsclient.data;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.logging.AAPSLogger;
public class NSMbg {
private static final Logger log = StacktraceLoggerWrapper.getLogger(LTag.NSCLIENT);
@Inject public AAPSLogger aapsLogger;
public long date;
public double mbg;
public String json;
public NSMbg(JSONObject json) {
public NSMbg(HasAndroidInjector injector) {
injector.androidInjector().inject(this);
}
public NSMbg(HasAndroidInjector injector, JSONObject json) {
this(injector);
try {
date = json.getLong("mills");
mbg = json.getDouble("mgdl");
this.json = json.toString();
} catch (JSONException e) {
log.error("Unhandled exception", e);
log.error("Data: " + json.toString());
aapsLogger.error("Unhandled exception", e);
aapsLogger.error("Data: " + json.toString());
}
}
public String id() {
try {
return new JSONObject(json).getString("_id");
} catch (JSONException e) {
return null;
}
}
}

View file

@ -1,147 +1,28 @@
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.interfaces.IobCobCalculatorInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.Round
import java.util.*
import javax.inject.Inject
import kotlin.math.roundToLong
class GlucoseStatus(private val injector: HasAndroidInjector) {
data class GlucoseStatus(
val glucose: Double,
val noise: Double = 0.0,
val delta: Double = 0.0,
val shortAvgDelta: Double = 0.0,
val longAvgDelta: Double = 0.0,
val date: Long = 0L
) {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorInterface
fun log(): String = "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " +
"Noise: " + DecimalFormatter.to0Decimal(noise) + " " +
"Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" +
"Short avg. delta: " + " " + DecimalFormatter.to2Decimal(shortAvgDelta) + " mg/dl " +
"Long avg. delta: " + DecimalFormatter.to2Decimal(longAvgDelta) + " mg/dl"
}
var glucose = 0.0
var noise = 0.0
var delta = 0.0
var avgDelta = 0.0
var shortAvgDelta = 0.0
var longAvgDelta = 0.0
var date = 0L
init {
injector.androidInjector().inject(this)
}
fun log(): String {
return "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " +
"Noise: " + DecimalFormatter.to0Decimal(noise) + " " +
"Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" +
"Short avg. delta: " + " " + DecimalFormatter.to2Decimal(shortAvgDelta) + " mg/dl " +
"Long avg. delta: " + DecimalFormatter.to2Decimal(longAvgDelta) + " mg/dl"
}
fun round(): GlucoseStatus {
glucose = Round.roundTo(glucose, 0.1)
noise = Round.roundTo(noise, 0.01)
delta = Round.roundTo(delta, 0.01)
avgDelta = Round.roundTo(avgDelta, 0.01)
shortAvgDelta = Round.roundTo(shortAvgDelta, 0.01)
longAvgDelta = Round.roundTo(longAvgDelta, 0.01)
return this
}
val glucoseStatusData: GlucoseStatus?
get() = getGlucoseStatusData(false)
fun getGlucoseStatusData(allowOldData: Boolean): GlucoseStatus? {
synchronized(iobCobCalculatorPlugin.dataLock) {
val data = iobCobCalculatorPlugin.bgReadings
val sizeRecords = data.size
if (sizeRecords == 0) {
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==0")
return null
}
if (data[0].timestamp < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
aapsLogger.debug(LTag.GLUCOSE, "oldData")
return null
}
val now = data[0]
val nowDate = now.timestamp
var change: Double
if (sizeRecords == 1) {
val status = GlucoseStatus(injector)
status.glucose = now.value
status.noise = 0.0
status.shortAvgDelta = 0.0
status.delta = 0.0
status.longAvgDelta = 0.0
status.avgDelta = 0.0 // for OpenAPS MA
status.date = nowDate
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==1")
return status.round()
}
val nowValueList = ArrayList<Double>()
val lastDeltas = ArrayList<Double>()
val shortDeltas = ArrayList<Double>()
val longDeltas = ArrayList<Double>()
// Use the latest sgv value in the now calculations
nowValueList.add(now.value)
for (i in 1 until sizeRecords) {
if (data[i].value > 38) {
val then = data[i]
val thenDate = then.timestamp
val minutesAgo = ((nowDate - thenDate) / (1000.0 * 60)).roundToLong()
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
change = now.value - then.value
val avgDel = change / minutesAgo * 5
aapsLogger.debug(LTag.GLUCOSE, "$then minutesAgo=$minutesAgo avgDelta=$avgDel")
// use the average of all data points in the last 2.5m for all further "now" calculations
if (0 < minutesAgo && minutesAgo < 2.5) {
// Keep and average all values within the last 2.5 minutes
nowValueList.add(then.value)
now.value = average(nowValueList)
// short_deltas are calculated from everything ~5-15 minutes ago
} else if (2.5 < minutesAgo && minutesAgo < 17.5) {
//console.error(minutesAgo, avgDelta);
shortDeltas.add(avgDel)
// last_deltas are calculated from everything ~5 minutes ago
if (2.5 < minutesAgo && minutesAgo < 7.5) {
lastDeltas.add(avgDel)
}
// long_deltas are calculated from everything ~20-40 minutes ago
} else if (17.5 < minutesAgo && minutesAgo < 42.5) {
longDeltas.add(avgDel)
} else {
// Do not process any more records after >= 42.5 minutes
break
}
}
}
val status = GlucoseStatus(injector)
status.glucose = now.value
status.date = nowDate
status.noise = 0.0 //for now set to nothing as not all CGMs report noise
status.shortAvgDelta = average(shortDeltas)
if (lastDeltas.isEmpty()) {
status.delta = status.shortAvgDelta
} else {
status.delta = average(lastDeltas)
}
status.longAvgDelta = average(longDeltas)
status.avgDelta = status.shortAvgDelta // for OpenAPS MA
aapsLogger.debug(LTag.GLUCOSE, status.log())
return status.round()
}
}
companion object {
fun average(array: ArrayList<Double>): Double {
var sum = 0.0
if (array.size == 0) return 0.0
for (value in array) {
sum += value
}
return sum / array.size
}
}
}
fun GlucoseStatus.asRounded() = copy(
glucose = Round.roundTo(glucose, 0.1),
noise = Round.roundTo(noise, 0.01),
delta = Round.roundTo(delta, 0.01),
shortAvgDelta = Round.roundTo(shortAvgDelta, 0.01),
longAvgDelta = Round.roundTo(longAvgDelta, 0.01)
)

View file

@ -0,0 +1,112 @@
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
import dagger.Reusable
import info.nightscout.androidaps.interfaces.IobCobCalculatorInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.utils.DateUtil
import java.util.*
import javax.inject.Inject
import kotlin.math.roundToLong
@Reusable
class GlucoseStatusProvider @Inject constructor(private val aapsLogger: AAPSLogger, private val iobCobCalculatorPlugin: IobCobCalculatorInterface) {
val glucoseStatusData: GlucoseStatus?
get() = getGlucoseStatusData()
fun getGlucoseStatusData(allowOldData: Boolean = false): GlucoseStatus? {
synchronized(iobCobCalculatorPlugin.dataLock) {
val data = iobCobCalculatorPlugin.bgReadings
val sizeRecords = data.size
if (sizeRecords == 0) {
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==0")
return null
}
if (data[0].timestamp < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
aapsLogger.debug(LTag.GLUCOSE, "oldData")
return null
}
val now = data[0]
val nowDate = now.timestamp
var change: Double
if (sizeRecords == 1) {
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==1")
return GlucoseStatus(
glucose = now.value,
noise = 0.0,
delta = 0.0,
shortAvgDelta = 0.0,
longAvgDelta = 0.0,
date = nowDate
).asRounded()
}
val nowValueList = ArrayList<Double>()
val lastDeltas = ArrayList<Double>()
val shortDeltas = ArrayList<Double>()
val longDeltas = ArrayList<Double>()
// Use the latest sgv value in the now calculations
nowValueList.add(now.value)
for (i in 1 until sizeRecords) {
if (data[i].value > 38) {
val then = data[i]
val thenDate = then.timestamp
val minutesAgo = ((nowDate - thenDate) / (1000.0 * 60)).roundToLong()
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
change = now.value - then.value
val avgDel = change / minutesAgo * 5
aapsLogger.debug(LTag.GLUCOSE, "$then minutesAgo=$minutesAgo avgDelta=$avgDel")
// use the average of all data points in the last 2.5m for all further "now" calculations
if (0 < minutesAgo && minutesAgo < 2.5) {
// Keep and average all values within the last 2.5 minutes
nowValueList.add(then.value)
now.value = average(nowValueList)
// short_deltas are calculated from everything ~5-15 minutes ago
} else if (2.5 < minutesAgo && minutesAgo < 17.5) {
//console.error(minutesAgo, avgDelta);
shortDeltas.add(avgDel)
// last_deltas are calculated from everything ~5 minutes ago
if (2.5 < minutesAgo && minutesAgo < 7.5) {
lastDeltas.add(avgDel)
}
// long_deltas are calculated from everything ~20-40 minutes ago
} else if (17.5 < minutesAgo && minutesAgo < 42.5) {
longDeltas.add(avgDel)
} else {
// Do not process any more records after >= 42.5 minutes
break
}
}
}
val shortAverageDelta = average(shortDeltas)
val delta = if (lastDeltas.isEmpty()) {
shortAverageDelta
} else {
average(lastDeltas)
}
return GlucoseStatus(
glucose = now.value,
date = nowDate,
noise = 0.0, //for now set to nothing as not all CGMs report noise
shortAvgDelta = shortAverageDelta,
delta = delta,
longAvgDelta = average(longDeltas),
).also { aapsLogger.debug(LTag.GLUCOSE, it.log()) }.asRounded()
}
}
companion object {
fun average(array: ArrayList<Double>): Double {
var sum = 0.0
if (array.size == 0) return 0.0
for (value in array) {
sum += value
}
return sum / array.size
}
}
}

View file

@ -1,14 +1,11 @@
package info.nightscout.androidaps.utils
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
import javax.inject.Singleton
/**
* Created by mike on 15.07.2016.
*/
@Singleton
class Translator @Inject internal constructor(
private val resourceHelper: ResourceHelper
@ -16,31 +13,33 @@ class Translator @Inject internal constructor(
fun translate(text: String): String =
when (text) {
CareportalEvent.BGCHECK -> resourceHelper.gs(R.string.careportal_bgcheck)
CareportalEvent.SNACKBOLUS -> resourceHelper.gs(R.string.careportal_snackbolus)
CareportalEvent.MEALBOLUS -> resourceHelper.gs(R.string.careportal_mealbolus)
CareportalEvent.CORRECTIONBOLUS -> resourceHelper.gs(R.string.careportal_correctionbolus)
CareportalEvent.CARBCORRECTION -> resourceHelper.gs(R.string.careportal_carbscorrection)
CareportalEvent.COMBOBOLUS -> resourceHelper.gs(R.string.careportal_combobolus)
CareportalEvent.ANNOUNCEMENT -> resourceHelper.gs(R.string.careportal_announcement)
CareportalEvent.NOTE -> resourceHelper.gs(R.string.careportal_note)
CareportalEvent.QUESTION -> resourceHelper.gs(R.string.careportal_question)
CareportalEvent.EXERCISE -> resourceHelper.gs(R.string.careportal_exercise)
CareportalEvent.SITECHANGE -> resourceHelper.gs(R.string.careportal_pumpsitechange)
CareportalEvent.PUMPBATTERYCHANGE -> resourceHelper.gs(R.string.careportal_pumpbatterychange)
CareportalEvent.SENSORSTART -> resourceHelper.gs(R.string.careportal_cgmsensorstart)
CareportalEvent.SENSORCHANGE -> resourceHelper.gs(R.string.careportal_cgmsensorinsert)
CareportalEvent.INSULINCHANGE -> resourceHelper.gs(R.string.careportal_insulincartridgechange)
CareportalEvent.TEMPBASALSTART -> resourceHelper.gs(R.string.careportal_tempbasalstart)
CareportalEvent.TEMPBASALEND -> resourceHelper.gs(R.string.careportal_tempbasalend)
CareportalEvent.PROFILESWITCH -> resourceHelper.gs(R.string.careportal_profileswitch)
CareportalEvent.TEMPORARYTARGET -> resourceHelper.gs(R.string.careportal_temporarytarget)
CareportalEvent.TEMPBASALCANCEL -> resourceHelper.gs(R.string.careportal_temporarytargetcancel)
CareportalEvent.OPENAPSOFFLINE -> resourceHelper.gs(R.string.careportal_openapsoffline)
CareportalEvent.MBG -> resourceHelper.gs(R.string.careportal_mbg)
CareportalEvent.FINGER -> resourceHelper.gs(R.string.glucosetype_finger)
CareportalEvent.SENSOR -> resourceHelper.gs(R.string.glucosetype_sensor)
CareportalEvent.MANUAL -> resourceHelper.gs(R.string.manual)
else -> resourceHelper.gs(R.string.unknown)
TherapyEvent.Type.FINGER_STICK_BG_VALUE.text -> resourceHelper.gs(R.string.careportal_bgcheck)
TherapyEvent.Type.SNACK_BOLUS.text -> resourceHelper.gs(R.string.careportal_snackbolus)
TherapyEvent.Type.MEAL_BOLUS.text -> resourceHelper.gs(R.string.careportal_mealbolus)
TherapyEvent.Type.CORRECTION_BOLUS.text -> resourceHelper.gs(R.string.careportal_correctionbolus)
TherapyEvent.Type.CARBS_CORRECTION.text -> resourceHelper.gs(R.string.careportal_carbscorrection)
TherapyEvent.Type.COMBO_BOLUS.text -> resourceHelper.gs(R.string.careportal_combobolus)
TherapyEvent.Type.ANNOUNCEMENT.text -> resourceHelper.gs(R.string.careportal_announcement)
TherapyEvent.Type.NOTE.text -> resourceHelper.gs(R.string.careportal_note)
TherapyEvent.Type.QUESTION.text -> resourceHelper.gs(R.string.careportal_question)
TherapyEvent.Type.EXERCISE.text -> resourceHelper.gs(R.string.careportal_exercise)
TherapyEvent.Type.CANNULA_CHANGE.text -> resourceHelper.gs(R.string.careportal_pumpsitechange)
TherapyEvent.Type.PUMP_BATTERY_CHANGE.text -> resourceHelper.gs(R.string.careportal_pumpbatterychange)
TherapyEvent.Type.SENSOR_STARTED.text -> resourceHelper.gs(R.string.careportal_cgmsensorstart)
TherapyEvent.Type.SENSOR_STOPPED.text -> resourceHelper.gs(R.string.careportal_cgm_sensor_stop)
TherapyEvent.Type.SENSOR_CHANGE.text -> resourceHelper.gs(R.string.careportal_cgmsensorinsert)
TherapyEvent.Type.INSULIN_CHANGE.text -> resourceHelper.gs(R.string.careportal_insulincartridgechange)
TherapyEvent.Type.DAD_ALERT.text -> resourceHelper.gs(R.string.careportal_dad_alert)
TherapyEvent.Type.TEMPORARY_BASAL_START.text -> resourceHelper.gs(R.string.careportal_tempbasalstart)
TherapyEvent.Type.TEMPORARY_BASAL_END.text -> resourceHelper.gs(R.string.careportal_tempbasalend)
TherapyEvent.Type.PROFILE_SWITCH.text -> resourceHelper.gs(R.string.careportal_profileswitch)
TherapyEvent.Type.TEMPORARY_TARGET.text -> resourceHelper.gs(R.string.careportal_temporarytarget)
TherapyEvent.Type.TEMPORARY_TARGET_CANCEL.text -> resourceHelper.gs(R.string.careportal_temporarytargetcancel)
TherapyEvent.Type.APS_OFFLINE.text -> resourceHelper.gs(R.string.careportal_openapsoffline)
TherapyEvent.Type.NS_MBG.text -> resourceHelper.gs(R.string.careportal_mbg)
TherapyEvent.MeterType.FINGER.text -> resourceHelper.gs(R.string.glucosetype_finger)
TherapyEvent.MeterType.SENSOR.text -> resourceHelper.gs(R.string.glucosetype_sensor)
TherapyEvent.MeterType.MANUAL.text -> resourceHelper.gs(R.string.manual)
else -> resourceHelper.gs(R.string.unknown)
}
}

View file

@ -3,7 +3,8 @@ package info.nightscout.androidaps.utils
import android.graphics.Color
import android.widget.TextView
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.utils.extensions.isOlderThan
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
import javax.inject.Singleton
@ -29,10 +30,10 @@ class WarnColors @Inject constructor(val resourceHelper: ResourceHelper) {
else -> normalColor
})
fun setColorByAge(view: TextView?, careportalEvent: CareportalEvent, warnThreshold: Double, urgentThreshold: Double) =
fun setColorByAge(view: TextView?, therapyEvent: TherapyEvent, warnThreshold: Double, urgentThreshold: Double) =
view?.setTextColor(when {
careportalEvent.isOlderThan(urgentThreshold) -> resourceHelper.gc(R.color.low)
careportalEvent.isOlderThan(warnThreshold) -> resourceHelper.gc(R.color.high)
else -> Color.WHITE
therapyEvent.isOlderThan(urgentThreshold) -> resourceHelper.gc(R.color.low)
therapyEvent.isOlderThan(warnThreshold) -> resourceHelper.gc(R.color.high)
else -> Color.WHITE
})
}

View file

@ -0,0 +1,91 @@
package info.nightscout.androidaps.utils.extensions
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.json.JSONObject
import java.util.concurrent.TimeUnit
fun TherapyEvent.age(useShortText: Boolean, resourceHelper: ResourceHelper): String {
val diff = DateUtil.computeDiff(timestamp, System.currentTimeMillis())
var days = " " + resourceHelper.gs(R.string.days) + " "
var hours = " " + resourceHelper.gs(R.string.hours) + " "
if (useShortText) {
days = resourceHelper.gs(R.string.shortday)
hours = resourceHelper.gs(R.string.shorthour)
}
return diff[TimeUnit.DAYS].toString() + days + diff[TimeUnit.HOURS] + hours
}
fun TherapyEvent.isOlderThan(hours: Double): Boolean {
return getHoursFromStart() > hours
}
fun TherapyEvent.getHoursFromStart(): Double {
return (System.currentTimeMillis() - timestamp) / (60 * 60 * 1000.0)
}
fun therapyEventFromNsMbg(mbg: NSMbg) =
TherapyEvent(
type = TherapyEvent.Type.NS_MBG,
timestamp = mbg.date,
glucose = mbg.mbg
).also {
it.interfaceIDs.nightscoutId = mbg.id()
}
/*
create fake object with nsID and isValid == false
*/
fun therapyEventFromNsIdForInvalidating(nsId: String): TherapyEvent =
therapyEventFromJson(
JSONObject()
.put("mills", 1)
.put("_id", nsId)
.put(NSUpload.ISVALID, false)
)!!
fun therapyEventFromJson(jsonObject: JSONObject): TherapyEvent? {
val units = JsonHelper.safeGetString(jsonObject, "units", Constants.MGDL)
val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
val type = TherapyEvent.Type.fromString(JsonHelper.safeGetString(jsonObject, "eventType", TherapyEvent.Type.NONE.text))
val duration = JsonHelper.safeGetLong(jsonObject, "duration")
val glucose = JsonHelper.safeGetDoubleAllowNull(jsonObject, "glucose")
val glucoseType = TherapyEvent.MeterType.fromString(JsonHelper.safeGetString(jsonObject, "glucoseType"))
val enteredBy = JsonHelper.safeGetStringAllowNull(jsonObject, "enteredBy", null)
val note = JsonHelper.safeGetStringAllowNull(jsonObject, "notes", null)
val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", null) ?: return null
val isValid = JsonHelper.safeGetBoolean(jsonObject, NSUpload.ISVALID, true)
val te = TherapyEvent(
timestamp = timestamp,
duration = TimeUnit.MINUTES.toMillis(duration),
units = units,
type = type,
glucose = glucose,
glucoseType = glucoseType,
enteredBy = enteredBy,
note = note,
isValid = isValid
)
te.interfaceIDs.nightscoutId = id
return te
}
fun isEvent5minBack(list: List<TherapyEvent>, time: Long): Boolean {
for (i in list.indices) {
val event = list[i]
if (event.timestamp <= time && event.timestamp > time - T.mins(5).msecs()) {
return true
}
}
return false
}

View file

@ -118,6 +118,7 @@
<string name="dismiss">POTVRDIT</string>
<!-- BlePreCheck-->
<string name="ble_not_supported">Bluetooth Low Energy nepodporováno.</string>
<string name="ble_not_supported_or_not_paired">Bluetooth Low Energy není podporováno, nebo zařízení není spárováno.</string>
<string name="ble_not_enabled">Bluetooth není povoleno.</string>
<string name="location_not_found_title">Zjišťování polohy není povoleno</string>
<string name="location_not_found_message">Pro vyhledání Bluetooth zařízení na novějších telefonech musí být povoleno zjišťování polohy. AAPS vás nesleduje a po provedení párování můžete tuto volbu opět zakázat.</string>

View file

@ -118,6 +118,7 @@
<string name="dismiss">VERWERFEN</string>
<!-- BlePreCheck-->
<string name="ble_not_supported">Bluetooth-Low-Energy nicht unterstützt.</string>
<string name="ble_not_supported_or_not_paired">Bluetooth Low Energy nicht unterstützt oder Gerät nicht verbunden.</string>
<string name="ble_not_enabled">Bluetooth nicht aktiviert.</string>
<string name="location_not_found_title">Standortdienst ist nicht aktiviert</string>
<string name="location_not_found_message">Auf neueren Geräten muss für die Bluetooth-Erkennung der Standortdienst aktiviert sein. AAPS speichert keine Standortdaten und der Dienst kann nach erfolgreichem Pairing wieder deaktiviert werden.</string>

View file

@ -12,7 +12,7 @@
<string name="goingtodeliver">%1$.2f U vont être injectées</string>
<string name="waitingforpump">Attente connection pompe</string>
<string name="connectingfor">Connexion à %1$d en cours</string>
<string name="bolusdelivering">%1$.2f U en cours d\'injection</string>
<string name="bolusdelivering">%1$.2f U ont été injectées</string>
<string name="handshaking">Connexion</string>
<string name="connecting">Connection en cours</string>
<string name="connected">Connectée</string>
@ -118,6 +118,7 @@
<string name="dismiss">REJETER</string>
<!-- BlePreCheck-->
<string name="ble_not_supported">Bluetooth Low Energy non pris en charge.</string>
<string name="ble_not_supported_or_not_paired">Bluetooth Low Energy non pris en charge ou appareil non appairé.</string>
<string name="ble_not_enabled">Bluetooth désactivé.</string>
<string name="location_not_found_title">Localisation désactivée</string>
<string name="location_not_found_message">La localisation doit être activée sur les nouveaux appareils pour que la recherche Bluetooth fonctionne. AAPS n\'enregistre pas votre localisation et la localisation peut être désactivée après l\'appairage.</string>

View file

@ -1,2 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
<resources>
<string name="error_only_numeric_digits_allowed">Seuls les chiffres sont autorisés.</string>
<string name="error_only_numeric_digits_range_allowed">Seuls les chiffres entre %1$s et %2$s sont autorisés.</string>
<string name="error_this_field_cannot_contain_special_character">Ce champ ne doit pas contenir de caractères spéciaux</string>
<string name="error_only_standard_letters_are_allowed">Seules les lettres sont autorisées</string>
<string name="error_field_must_not_be_empty">Le champ ne doit pas être vide</string>
<string name="error_email_address_not_valid">Adresse e-mail invalide</string>
<string name="error_creditcard_number_not_valid">Le numéro de carte de crédit est invalide</string>
<string name="error_phone_not_valid">Numéro de téléphone invalide</string>
<string name="error_domain_not_valid">Nom de domaine invalide</string>
<string name="error_ip_not_valid">Adresse IP invalide</string>
<string name="error_url_not_valid">Le lien web (url) est invalide</string>
<string name="error_notvalid_personname">Prénom ou le nom de famille invalide.</string>
<string name="error_notvalid_personfullname">Nom complet invalide.</string>
<string name="error_date_not_valid">Format invalide</string>
<string name="error_mustbe4digitnumber">Doit avoir 4 chiffres</string>
<string name="error_mustbe6digitnumber">Doit avoir 6 chiffres</string>
<string name="error_mustbe12hexadidits">Doit avoir 12 caractères parmi ABCDEF0123456789</string>
<string name="error_mustbe8hexadidits">Doit avoir 8 caractères parmi ABCDEF0123456789</string>
<string name="error_mustbe4hexadidits">Doit avoir 4 caractères parmi ABCDEF0123456789</string>
<string name="error_not_a_minimum_length">Longueur minimale non respectée</string>
<string name="error_pin_not_valid">Le PIN doit avoir entre 3 et 6 chiffres différents et non en série</string>
</resources>

View file

@ -118,6 +118,7 @@
<string name="dismiss">RIMUOVI</string>
<!-- BlePreCheck-->
<string name="ble_not_supported">Bluetooth Low Energy non supportato.</string>
<string name="ble_not_supported_or_not_paired">Bluetooth Low Energy non supportato o dispositivo non associato.</string>
<string name="ble_not_enabled">Bluetooth non abilitato.</string>
<string name="location_not_found_title">La localizzazione non è abilitata</string>
<string name="location_not_found_message">Affinché la ricerca bluetooth funzioni sui dispositivi più recenti, la localizzazione deve essere abilitata, ma può essere disabilitata dopo l\'associazione. AAPS non tiene traccia della tua posizione.</string>

View file

@ -118,6 +118,7 @@
<string name="dismiss">Avvis</string>
<!-- BlePreCheck-->
<string name="ble_not_supported">Lavenergi Bluetooth BLE er ikke støttet.</string>
<string name="ble_not_supported_or_not_paired">Bluetooth Low Energy er ikke støttet eller enheten er ikke paret.</string>
<string name="ble_not_enabled">Bluetooth er ikke aktivert.</string>
<string name="location_not_found_title">Stedstjeneste er ikke aktivert</string>
<string name="location_not_found_message">Bluetooth søk på nye mobiler virker bare når posisjonstjeneste er aktivert. AAPS lagrer ikke dine posisjonsdata og den kan derfor slås av etter vellykket sammenkobling.</string>

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