Merge branch 'dev2_dana_combo_only' of github.com:nightscout/AndroidAPS into dev2_dana_combo_only

This commit is contained in:
Andy Rozman 2021-05-01 11:26:53 +01:00
commit 5abdba0579
230 changed files with 9006 additions and 2160 deletions

View file

@ -14,7 +14,7 @@ import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.androidaps.danars.DanaRSPlugin
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.events.EventRebuildTabs
import info.nightscout.androidaps.interfaces.PluginBase

View file

@ -7,14 +7,16 @@ import android.text.TextWatcher
import android.view.Menu
import android.widget.PopupMenu
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.data.PureProfile
import info.nightscout.androidaps.data.defaultProfile.DefaultProfile
import info.nightscout.androidaps.data.defaultProfile.DefaultProfileDPV
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
import info.nightscout.androidaps.databinding.ActivityProfilehelperBinding
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -24,7 +26,6 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.utils.stats.TddCalculator
import java.text.DecimalFormat
import javax.inject.Inject
@ -40,7 +41,7 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var repository: AppRepository
enum class ProfileType {
MOTOL_DEFAULT,
@ -61,7 +62,7 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
private lateinit var profileList: ArrayList<CharSequence>
private val profileUsed = arrayOf(0, 0)
private lateinit var profileSwitch: List<ProfileSwitch>
private lateinit var profileSwitch: List<EffectiveProfileSwitch>
private val profileSwitchUsed = arrayOf(0, 0)
private lateinit var binding: ActivityProfilehelperBinding
@ -114,12 +115,12 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
}
// Profile switch
profileSwitch = databaseHelper.getProfileSwitchData(dateUtil.now() - T.months(2).msecs(), true)
profileSwitch = repository.getEffectiveProfileSwitchDataFromTime(dateUtil.now() - T.months(2).msecs(), true).blockingGet()
binding.profileswitchList.setOnClickListener {
PopupMenu(this, binding.profileswitchList).apply {
var order = 0
for (name in profileSwitch) menu.add(Menu.NONE, order, order++, name.customizedName)
for (name in profileSwitch) menu.add(Menu.NONE, order, order++, name.originalCustomizedName)
setOnMenuItemClickListener { item ->
binding.profileswitchList.setText(item.title)
profileSwitchUsed[tabSelected] = item.itemId
@ -212,9 +213,8 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
pvd.arguments = Bundle().also {
it.putLong("time", dateUtil.now())
it.putInt("mode", ProfileViewerDialog.Mode.PROFILE_COMPARE.ordinal)
it.putString("customProfile", profile0.data.toString())
it.putString("customProfile2", profile1.data.toString())
it.putString("customProfileUnits", profileFunction.getUnits())
it.putString("customProfile", profile0.jsonObject.toString())
it.putString("customProfile2", profile1.jsonObject.toString())
it.putString("customProfileName", getProfileName(ageUsed[0], tddUsed[0], weightUsed[0], pctUsed[0] / 100.0, 0) + "\n" + getProfileName(ageUsed[1], tddUsed[1], weightUsed[1], pctUsed[1] / 100.0, 1))
}
}.show(supportFragmentManager, "ProfileViewDialog")
@ -227,14 +227,14 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
switchTab(0, typeSelected[0], false)
}
private fun getProfile(age: Double, tdd: Double, weight: Double, basalPct: Double, tab: Int): Profile? =
private fun getProfile(age: Double, tdd: Double, weight: Double, basalPct: Double, tab: Int): PureProfile? =
try { // profile must not exist
when (typeSelected[tab]) {
ProfileType.MOTOL_DEFAULT -> defaultProfile.profile(age, tdd, weight, profileFunction.getUnits())
ProfileType.DPV_DEFAULT -> defaultProfileDPV.profile(age, tdd, basalPct, profileFunction.getUnits())
ProfileType.CURRENT -> profileFunction.getProfile()?.convertToNonCustomizedProfile()
ProfileType.CURRENT -> profileFunction.getProfile()?.convertToNonCustomizedProfile(dateUtil)
ProfileType.AVAILABLE_PROFILE -> activePlugin.activeProfileSource.profile?.getSpecificProfile(profileList[profileUsed[tab]].toString())
ProfileType.PROFILE_SWITCH -> profileSwitch[profileSwitchUsed[tab]].profileObject?.convertToNonCustomizedProfile()
ProfileType.PROFILE_SWITCH -> ProfileSealed.EPS(profileSwitch[profileSwitchUsed[tab]]).convertToNonCustomizedProfile(dateUtil)
}
} catch (e: Exception) {
null
@ -246,7 +246,7 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
ProfileType.DPV_DEFAULT -> resourceHelper.gs(R.string.formatwittddandpct, age, tdd, (basalSumPct * 100).toInt())
ProfileType.CURRENT -> profileFunction.getProfileName()
ProfileType.AVAILABLE_PROFILE -> profileList[profileUsed[tab]].toString()
ProfileType.PROFILE_SWITCH -> profileSwitch[profileSwitchUsed[tab]].customizedName
ProfileType.PROFILE_SWITCH -> profileSwitch[profileSwitchUsed[tab]].originalCustomizedName
}
private fun storeValues() {
@ -289,7 +289,7 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
if (profileList.isNotEmpty())
binding.availableProfileList.setText(profileList[profileUsed[tabSelected]].toString())
if (profileSwitch.isNotEmpty())
binding.profileswitchList.setText(profileSwitch[profileSwitchUsed[tabSelected]].customizedName)
binding.profileswitchList.setText(profileSwitch[profileSwitchUsed[tabSelected]].originalCustomizedName)
}
private fun setBackgroundColorOnSelected(tab: Int) {

View file

@ -71,9 +71,8 @@ class SurveyActivity : NoSplashAppCompatActivity() {
pvd.arguments = Bundle().also {
it.putLong("time", dateUtil.now())
it.putInt("mode", ProfileViewerDialog.Mode.PROFILE_COMPARE.ordinal)
it.putString("customProfile", runningProfile.data.toString())
it.putString("customProfile2", profile.data.toString())
it.putString("customProfileUnits", profile.units)
it.putString("customProfile", runningProfile.toPureNsJson(dateUtil).toString())
it.putString("customProfile2", profile.jsonObject.toString())
it.putString("customProfileName", "Age: $age TDD: $tdd Weight: $weight")
}
}.show(supportFragmentManager, "ProfileViewDialog")

View file

@ -1,7 +1,12 @@
package info.nightscout.androidaps.data.defaultProfile
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.ProfileImplOld
import info.nightscout.androidaps.data.PureProfile
import info.nightscout.androidaps.extensions.pureProfileFromJson
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.Round
import org.json.JSONArray
import org.json.JSONObject
@ -10,14 +15,14 @@ import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DefaultProfile @Inject constructor(val injector: HasAndroidInjector) {
class DefaultProfile @Inject constructor(val dateUtil: DateUtil) {
var oneToFive: TreeMap<Double, Array<Double>> = TreeMap()
var sixToEleven: TreeMap<Double, Array<Double>> = TreeMap()
var twelveToSeventeen: TreeMap<Double, Array<Double>> = TreeMap()
var eighteenToTwentyfor: TreeMap<Double, Array<Double>> = TreeMap()
var eighteenToTwentyFour: TreeMap<Double, Array<Double>> = TreeMap()
fun profile(age: Double, tdd: Double, weight: Double, units: String): Profile? {
fun profile(age: Double, tdd: Double, weight: Double, units: GlucoseUnit): PureProfile? {
val profile = JSONObject()
if (age >= 1 && age < 6) {
val _tdd = if (tdd == 0.0) 0.6 * weight else tdd
@ -49,8 +54,8 @@ class DefaultProfile @Inject constructor(val injector: HasAndroidInjector) {
profile.put("timezone", TimeZone.getDefault().id)
profile.put("target_high", JSONArray().put(JSONObject().put("time", "00:00").put("value", Profile.fromMgdlToUnits(108.0, units))))
profile.put("target_low", JSONArray().put(JSONObject().put("time", "00:00").put("value", Profile.fromMgdlToUnits(108.0, units))))
profile.put("units", units)
return Profile(injector, profile, units)
profile.put("units", units.asText)
return pureProfileFromJson(profile, dateUtil)
}
init {
@ -148,7 +153,7 @@ class DefaultProfile @Inject constructor(val injector: HasAndroidInjector) {
return array
}
private fun singleValueArrayFromMmolToUnits(value: Double, sample: Array<Double>, units: String): JSONArray {
private fun singleValueArrayFromMmolToUnits(value: Double, sample: Array<Double>, units: GlucoseUnit): JSONArray {
val array = JSONArray()
array.put(JSONObject().put("time", "00:00").put("value", Profile.fromMmolToUnits(value + sample[0],units)).put("timeAsSeconds", 0 * 3600))
array.put(JSONObject().put("time", "06:00").put("value", Profile.fromMmolToUnits(value + sample[1],units)).put("timeAsSeconds", 6 * 3600))

View file

@ -1,8 +1,12 @@
package info.nightscout.androidaps.data.defaultProfile
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.data.ProfileImplOld
import info.nightscout.androidaps.data.PureProfile
import info.nightscout.androidaps.extensions.pureProfileFromJson
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.utils.DateUtil
import org.json.JSONArray
import org.json.JSONObject
import java.util.*
@ -10,13 +14,13 @@ import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DefaultProfileDPV @Inject constructor(val injector: HasAndroidInjector) {
class DefaultProfileDPV @Inject constructor(val injector: HasAndroidInjector, val dateUtil: DateUtil) {
var oneToFive = arrayOf(3.97, 3.61, 3.46, 3.70, 3.76, 3.87, 4.18, 4.01, 3.76, 3.54, 3.15, 2.80, 2.86, 3.21, 3.61, 3.97, 4.43, 4.96, 5.10, 5.50, 5.81, 6.14, 5.52, 5.10)
var sixToEleven = arrayOf(4.20, 4.27, 4.41, 4.62, 4.92, 5.09, 5.01, 4.47, 3.89, 3.33, 3.10, 2.91, 2.97, 3.08, 3.36, 3.93, 4.52, 4.76, 4.69, 4.63, 4.63, 4.47, 4.47, 4.31)
var twelveToEighteen = arrayOf(3.47, 3.80, 4.31, 4.95, 5.59, 6.11, 5.89, 5.11, 4.31, 3.78, 3.55, 3.39, 3.35, 3.39, 3.64, 3.97, 4.53, 4.59, 4.50, 4.00, 3.69, 3.39, 3.35, 3.35)
fun profile(age: Double, tdd: Double, basalSumPct: Double, units: String): Profile? {
fun profile(age: Double, tdd: Double, basalSumPct: Double, units: GlucoseUnit): PureProfile? {
val basalSum = tdd * basalSumPct
val profile = JSONObject()
if (age >= 1 && age < 6) {
@ -40,8 +44,8 @@ class DefaultProfileDPV @Inject constructor(val injector: HasAndroidInjector) {
profile.put("timezone", TimeZone.getDefault().id)
profile.put("target_high", JSONArray().put(JSONObject().put("time", "00:00").put("value", Profile.fromMgdlToUnits(108.0, units))))
profile.put("target_low", JSONArray().put(JSONObject().put("time", "00:00").put("value", Profile.fromMgdlToUnits(108.0, units))))
profile.put("units", units)
return Profile(injector, profile, units)
profile.put("units", units.asText)
return pureProfileFromJson(profile, dateUtil)
}
private fun arrayToJson(b: Array<Double>, basalSum: Double): JSONArray {
@ -59,7 +63,7 @@ class DefaultProfileDPV @Inject constructor(val injector: HasAndroidInjector) {
return array
}
private fun singleValueArrayFromMmolToUnits(value: Double, units: String): JSONArray {
private fun singleValueArrayFromMmolToUnits(value: Double, units: GlucoseUnit): JSONArray {
val array = JSONArray()
array.put(JSONObject().put("time", "00:00").put("value", Profile.fromMmolToUnits(value, units)).put("timeAsSeconds", 0 * 3600))
return array

View file

@ -74,5 +74,13 @@ class CompatDBHelper @Inject constructor(
aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged")
rxBus.send(EventFoodDatabaseChanged())
}
it.filterIsInstance<ProfileSwitch>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventProfileNeedsUpdate")
rxBus.send(EventProfileSwitchChanged())
}
it.filterIsInstance<EffectiveProfileSwitch>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventProfileNeedsUpdate")
rxBus.send(EventProfileSwitchChanged())
}
}
}

View file

@ -16,31 +16,19 @@ import com.j256.ormlite.stmt.Where;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import info.nightscout.androidaps.dana.comm.RecordTypes;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.events.EventReloadProfileSwitchData;
import info.nightscout.androidaps.interfaces.ActivePlugin;
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
import info.nightscout.androidaps.interfaces.ProfileSource;
import info.nightscout.androidaps.interfaces.ProfileStore;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
@ -48,7 +36,6 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader;
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.PercentageSplitter;
/**
* This Helper contains all resource to provide a central DB management functionality. Only methods handling
@ -75,9 +62,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public static Long earliestDataChange = null;
private static final ScheduledExecutorService profileSwitchEventWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledProfileSwitchEventPost = null;
private int oldVersion = 0;
private int newVersion = 0;
@ -96,7 +80,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
TableUtils.createTableIfNotExists(connectionSource, TemporaryBasal.class);
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class);
TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class);
TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class);
@ -124,7 +107,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, ProfileSwitch.class, true);
onCreate(database, connectionSource);
} else if (oldVersion < 10) {
TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class);
@ -171,20 +153,17 @@ 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, ProfileSwitch.class, true);
TableUtils.dropTable(connectionSource, OmnipodHistoryRecord.class, true);
TableUtils.createTableIfNotExists(connectionSource, DanaRHistoryRecord.class);
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
TableUtils.createTableIfNotExists(connectionSource, TemporaryBasal.class);
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
TableUtils.createTableIfNotExists(connectionSource, OmnipodHistoryRecord.class);
updateEarliestDataChange(0);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
virtualPumpPlugin.setFakingStatus(true);
scheduleProfileSwitchChange();
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
@ -196,16 +175,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
);
}
public void resetProfileSwitch() {
try {
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
scheduleProfileSwitchChange();
}
// ------------------ getDao -------------------------------------------
private Dao<DanaRHistoryRecord, String> getDaoDanaRHistory() throws SQLException {
@ -224,10 +193,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return getDao(ExtendedBolus.class);
}
private Dao<ProfileSwitch, Long> getDaoProfileSwitch() throws SQLException {
return getDao(ProfileSwitch.class);
}
private Dao<InsightPumpID, Long> getDaoInsightPumpID() throws SQLException {
return getDao(InsightPumpID.class);
}
@ -580,104 +545,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
// ---------------- ProfileSwitch handling ---------------
public List<ProfileSwitch> getProfileSwitchData(long from, boolean ascending) {
try {
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
List<ProfileSwitch> profileSwitches;
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
queryBuilder.orderBy("date", ascending);
queryBuilder.limit(100L);
Where where = queryBuilder.where();
where.ge("date", from);
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
profileSwitches = daoProfileSwitch.query(preparedQuery);
//add last one without duration
ProfileSwitch last = getLastProfileSwitchWithoutDuration();
if (last != null) {
if (!isInList(profileSwitches, last))
profileSwitches.add(last);
}
return profileSwitches;
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return new ArrayList<>();
}
boolean isInList(List<ProfileSwitch> profileSwitches, ProfileSwitch last) {
for (ProfileSwitch ps : profileSwitches) {
if (ps.isEqual(last)) return true;
}
return false;
}
public List<ProfileSwitch> getAllProfileSwitches() {
try {
return getDaoProfileSwitch().queryForAll();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return Collections.emptyList();
}
@Nullable
private ProfileSwitch getLastProfileSwitchWithoutDuration() {
try {
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
List<ProfileSwitch> profileSwitches;
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
queryBuilder.orderBy("date", false);
queryBuilder.limit(1L);
Where where = queryBuilder.where();
where.eq("durationInMinutes", 0);
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
profileSwitches = daoProfileSwitch.query(preparedQuery);
if (profileSwitches.size() > 0)
return profileSwitches.get(0);
else
return null;
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return null;
}
public List<ProfileSwitch> getProfileSwitchEventsFromTime(long mills, boolean ascending) {
try {
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
List<ProfileSwitch> profileSwitches;
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
queryBuilder.orderBy("date", ascending);
queryBuilder.limit(100L);
Where where = queryBuilder.where();
where.ge("date", mills);
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
profileSwitches = daoProfileSwitch.query(preparedQuery);
return profileSwitches;
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public List<ProfileSwitch> getProfileSwitchEventsFromTime(long from, long to, boolean ascending) {
try {
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
List<ProfileSwitch> profileSwitches;
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
queryBuilder.orderBy("date", ascending);
queryBuilder.limit(100L);
Where where = queryBuilder.where();
where.between("date", from, to);
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
profileSwitches = daoProfileSwitch.query(preparedQuery);
return profileSwitches;
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return new ArrayList<>();
}
/*
public boolean createOrUpdate(ProfileSwitch profileSwitch) {
try {
ProfileSwitch old;
@ -767,7 +635,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
scheduledProfileSwitchEventPost = profileSwitchEventWorker.schedule(task, sec, TimeUnit.SECONDS);
}
*/
/*
{
"_id":"592fa43ed97496a80da913d2",
@ -779,6 +647,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
"NSCLIENT_ID":1496294454309,
}
*/
/*
public void createProfileSwitchFromJsonIfNotExists(JSONObject trJson) {
try {
@ -800,9 +669,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
ProfileSource profileSource = activePlugin.getActiveProfileSource();
ProfileStore store = profileSource.getProfile();
if (store != null) {
Profile profile = store.getSpecificProfile(profileSwitch.profileName);
PureProfile profile = store.getSpecificProfile(profileSwitch.profileName);
if (profile != null) {
profileSwitch.profileJson = profile.getData().toString();
profileSwitch.profileJson = profile.getJsonObject().toString();
aapsLogger.debug(LTag.DATABASE, "Profile switch prefilled with JSON from local store");
// Update data in NS
nsUpload.updateProfileSwitch(profileSwitch, dateUtil);
@ -850,7 +719,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
return null;
}
*/
// ---------------- Insight history handling ---------------
public void createOrUpdate(InsightHistoryOffset offset) {
@ -1059,7 +928,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public long getCountOfAllRows() {
try {
return getDaoExtendedBolus().countOf()
+ getDaoProfileSwitch().countOf()
+ getDaoTemporaryBasal().countOf();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);

View file

@ -88,10 +88,6 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
return MainApp.Companion.getDbHelper().findOmnipodHistoryRecordByPumpId(pumpId);
}
@NonNull @Override public List<ProfileSwitch> getProfileSwitchData(long from, boolean ascending) {
return MainApp.Companion.getDbHelper().getProfileSwitchData(from, ascending);
}
@Override public void createOrUpdate(@NonNull InsightBolusID record) {
MainApp.Companion.getDbHelper().createOrUpdate(record);
}
@ -124,18 +120,6 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
return MainApp.Companion.getDbHelper().getPumpStoppedEvent(pumpSerial, before);
}
@Override public void createOrUpdate(@NonNull ProfileSwitch profileSwitch) {
MainApp.Companion.getDbHelper().createOrUpdate(profileSwitch);
}
@Override public void deleteProfileSwitchById(@NonNull String _id) {
MainApp.Companion.getDbHelper().deleteProfileSwitchById(_id);
}
@Override public void createProfileSwitchFromJsonIfNotExists(@NonNull JSONObject trJson) {
MainApp.Companion.getDbHelper().createProfileSwitchFromJsonIfNotExists(trJson);
}
@Override public void resetDatabases() {
MainApp.Companion.getDbHelper().resetDatabases();
}
@ -144,30 +128,10 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
MainApp.Companion.getDbHelper().createOrUpdate(record);
}
@Override public void delete(@NonNull ProfileSwitch profileSwitch) {
MainApp.Companion.getDbHelper().delete(profileSwitch);
}
@NonNull @Override public List<ProfileSwitch> getProfileSwitchEventsFromTime(long from, long to, boolean ascending) {
return MainApp.Companion.getDbHelper().getProfileSwitchEventsFromTime(from, to, ascending);
}
@NonNull @Override public List<ProfileSwitch> getProfileSwitchEventsFromTime(long mills, boolean ascending) {
return MainApp.Companion.getDbHelper().getProfileSwitchEventsFromTime(mills, ascending);
}
@NonNull @Override public List<ProfileSwitch> getAllProfileSwitches() {
return MainApp.Companion.getDbHelper().getAllProfileSwitches();
}
@NonNull @Override public List<OHQueueItem> getAllOHQueueItems(long maxEntries) {
return MainApp.Companion.getDbHelper().getAllOHQueueItems(maxEntries);
}
@Override public void resetProfileSwitch() {
MainApp.Companion.getDbHelper().resetProfileSwitch();
}
@Override public long getOHQueueSize() {
return MainApp.Companion.getDbHelper().getOHQueueSize();
}

View file

@ -7,7 +7,7 @@ import dagger.android.AndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.automation.di.AutomationModule
import info.nightscout.androidaps.combo.di.ComboModule
import info.nightscout.androidaps.core.di.CoreModule
import info.nightscout.androidaps.di.CoreModule
import info.nightscout.androidaps.dana.di.DanaModule
import info.nightscout.androidaps.danar.di.DanaRModule
import info.nightscout.androidaps.danars.di.DanaRSModule

View file

@ -6,13 +6,13 @@ import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.databinding.DialogCalibrationBinding
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
@ -57,13 +57,13 @@ class CalibrationDialog : DialogFragmentWithDate() {
val units = profileFunction.getUnits()
val bg = Profile.fromMgdlToUnits(glucoseStatusProvider.glucoseStatusData?.glucose
?: 0.0, units)
if (units == Constants.MMOL)
if (units == GlucoseUnit.MMOL)
binding.bg.setParams(savedInstanceState?.getDouble("bg")
?: bg, 2.0, 30.0, 0.1, DecimalFormat("0.0"), false, binding.okcancel.ok)
else
binding.bg.setParams(savedInstanceState?.getDouble("bg")
?: bg, 36.0, 500.0, 1.0, DecimalFormat("0"), false, binding.okcancel.ok)
binding.units.text = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
binding.units.text = if (units == GlucoseUnit.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
}
override fun onDestroyView() {
@ -74,14 +74,14 @@ class CalibrationDialog : DialogFragmentWithDate() {
override fun submit(): Boolean {
if (_binding == null) return false
val units = profileFunction.getUnits()
val unitLabel = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
val unitLabel = if (units == GlucoseUnit.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
val actions: LinkedList<String?> = LinkedList()
val bg = binding.bg.value ?: return false
actions.add(resourceHelper.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, bg) + " " + unitLabel)
if (bg > 0) {
activity?.let { activity ->
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.overview_calibration), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
uel.log(Action.CALIBRATION, Sources.CalibrationDialog, ValueWithUnit.fromGlucoseUnit(bg, units))
uel.log(Action.CALIBRATION, Sources.CalibrationDialog, ValueWithUnit.fromGlucoseUnit(bg, units.asText))
xdripCalibrations.sendIntent(bg)
})
}

View file

@ -8,11 +8,10 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.UserEntry.Action
@ -22,6 +21,7 @@ import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAnd
import info.nightscout.androidaps.databinding.DialogCarbsBinding
import info.nightscout.androidaps.extensions.formatColor
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.LTag
@ -184,7 +184,7 @@ class CarbsDialog : DialogFragmentWithDate() {
val hypoTTDuration = defaultValueHelper.determineHypoTTDuration()
val hypoTT = defaultValueHelper.determineHypoTT()
val actions: LinkedList<String?> = LinkedList()
val unitLabel = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
val unitLabel = if (units == GlucoseUnit.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
val useAlarm = binding.alarmCheckBox.isChecked
val activitySelected = binding.activityTt.isChecked
@ -226,7 +226,7 @@ class CarbsDialog : DialogFragmentWithDate() {
activitySelected -> {
uel.log(Action.TT, Sources.CarbDialog,
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.ACTIVITY),
ValueWithUnit.fromGlucoseUnit(activityTT, units),
ValueWithUnit.fromGlucoseUnit(activityTT, units.asText),
ValueWithUnit.Minute(activityTTDuration))
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
timestamp = System.currentTimeMillis(),
@ -245,7 +245,7 @@ class CarbsDialog : DialogFragmentWithDate() {
eatingSoonSelected -> {
uel.log(Action.TT, Sources.CarbDialog,
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.EATING_SOON),
ValueWithUnit.fromGlucoseUnit(eatingSoonTT, units),
ValueWithUnit.fromGlucoseUnit(eatingSoonTT, units.asText),
ValueWithUnit.Minute(eatingSoonTTDuration))
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
timestamp = System.currentTimeMillis(),
@ -264,7 +264,7 @@ class CarbsDialog : DialogFragmentWithDate() {
hypoSelected -> {
uel.log(Action.TT, Sources.CarbDialog,
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.HYPOGLYCEMIA),
ValueWithUnit.fromGlucoseUnit(hypoTT, units),
ValueWithUnit.fromGlucoseUnit(hypoTT, units.asText),
ValueWithUnit.Minute(hypoTTDuration))
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
timestamp = System.currentTimeMillis(),

View file

@ -12,7 +12,7 @@ import com.google.common.base.Joiner
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.entities.TherapyEvent
@ -29,6 +29,7 @@ import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.Translator
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.extensions.fromConstant
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.utils.resources.ResourceHelper
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
@ -151,7 +152,7 @@ class CareDialog : DialogFragmentWithDate() {
}
}
if (profileFunction.getUnits() == Constants.MMOL) {
if (profileFunction.getUnits() == GlucoseUnit.MMOL) {
binding.bgunits.text = resourceHelper.gs(R.string.mmol)
binding.bg.setParams(savedInstanceState?.getDouble("bg")
?: bg, 2.0, 30.0, 0.1, DecimalFormat("0.0"), false, binding.okcancel.ok, bgTextWatcher)
@ -173,7 +174,7 @@ class CareDialog : DialogFragmentWithDate() {
override fun submit(): Boolean {
val enteredBy = sp.getString("careportal_enteredby", "AndroidAPS")
val unitResId = if (profileFunction.getUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol
val unitResId = if (profileFunction.getUnits() == GlucoseUnit.MGDL) R.string.mgdl else R.string.mmol
eventTime -= eventTime % 1000
@ -203,7 +204,7 @@ class CareDialog : DialogFragmentWithDate() {
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.fromGlucoseUnit(binding.bg.value.toDouble(), profileFunction.getUnits()))
valuesWithUnit.add(ValueWithUnit.fromGlucoseUnit(binding.bg.value.toDouble(), profileFunction.getUnits().asText))
valuesWithUnit.add(ValueWithUnit.TherapyEventMeterType(meterType))
}
if (options == EventType.NOTE || options == EventType.EXERCISE) {

View file

@ -8,12 +8,9 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.entities.TemporaryTarget
@ -21,10 +18,6 @@ import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
import info.nightscout.androidaps.databinding.DialogInsulinBinding
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
@ -34,6 +27,7 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.extensions.formatColor
import info.nightscout.androidaps.utils.extensions.toSignedString
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.utils.resources.ResourceHelper
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
@ -158,7 +152,7 @@ class InsulinDialog : DialogFragmentWithDate() {
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(insulin)).value()
val actions: LinkedList<String?> = LinkedList()
val units = profileFunction.getUnits()
val unitLabel = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
val unitLabel = if (units == GlucoseUnit.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
val recordOnlyChecked = binding.recordOnly.isChecked
val eatingSoonChecked = binding.startEatingSoonTt.isChecked
@ -190,7 +184,7 @@ class InsulinDialog : DialogFragmentWithDate() {
uel.log(Action.TT, Sources.InsulinDialog,
notes,
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.EATING_SOON),
ValueWithUnit.fromGlucoseUnit(eatingSoonTT, units),
ValueWithUnit.fromGlucoseUnit(eatingSoonTT, units.asText),
ValueWithUnit.Minute(eatingSoonTTDuration))
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
timestamp = System.currentTimeMillis(),

View file

@ -8,17 +8,18 @@ import android.widget.ArrayAdapter
import com.google.common.base.Joiner
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.databinding.DialogProfileswitchBinding
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.resources.ResourceHelper
import io.reactivex.disposables.CompositeDisposable
import java.text.DecimalFormat
import java.util.*
import javax.inject.Inject
@ -27,12 +28,14 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var repository: AppRepository
@Inject lateinit var uel: UserEntryLogger
private var profileIndex: Int? = null
private val disposable = CompositeDisposable()
private var _binding: DialogProfileswitchBinding? = null
// This property is only valid between onCreateView and
@ -78,17 +81,17 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
binding.profile.setSelection(profileIndex as Int)
else
for (p in profileList.indices)
if (profileList[p] == profileFunction.getProfileName(false))
if (profileList[p] == profileFunction.getOriginalProfileName())
binding.profile.setSelection(p)
} ?: return
treatmentsPlugin.getProfileSwitchFromHistory(dateUtil.now())?.let { ps ->
if (ps.isCPP) {
profileFunction.getProfile()?.let { profile ->
if (profile.percentage != 100 || profile.timeshift != 0) {
binding.reuselayout.visibility = View.VISIBLE
binding.reusebutton.text = resourceHelper.gs(R.string.reuse_profile_pct_hours, ps.percentage, ps.timeshift)
binding.reusebutton.text = resourceHelper.gs(R.string.reuse_profile_pct_hours, profile.percentage, profile.timeshift)
binding.reusebutton.setOnClickListener {
binding.percentage.value = ps.percentage.toDouble()
binding.timeshift.value = ps.timeshift.toDouble()
binding.percentage.value = profile.percentage.toDouble()
binding.timeshift.value = profile.timeshift.toDouble()
}
} else {
binding.reuselayout.visibility = View.GONE
@ -98,6 +101,7 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
override fun onDestroyView() {
super.onDestroyView()
disposable.clear()
_binding = null
}
@ -108,10 +112,10 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
val actions: LinkedList<String> = LinkedList()
val duration = binding.duration.value?.toInt() ?: return false
if (duration > 0)
if (duration > 0L)
actions.add(resourceHelper.gs(R.string.duration) + ": " + resourceHelper.gs(R.string.format_mins, duration))
val profile = binding.profile.selectedItem.toString()
actions.add(resourceHelper.gs(R.string.profile) + ": " + profile)
val profileName = binding.profile.selectedItem.toString()
actions.add(resourceHelper.gs(R.string.profile) + ": " + profileName)
val percent = binding.percentage.value.toInt()
if (percent != 100)
actions.add(resourceHelper.gs(R.string.percent) + ": " + percent + "%")
@ -126,15 +130,20 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
activity?.let { activity ->
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
profileFunction.createProfileSwitch(profileStore,
profileName = profileName,
durationInMinutes = duration,
percentage = percent,
timeShiftInHours = timeShift,
timestamp = eventTime)
uel.log(Action.PROFILE_SWITCH,
Sources.ProfileSwitchDialog,
notes,
ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged },
ValueWithUnit.SimpleString(profile),
ValueWithUnit.SimpleString(profileName),
ValueWithUnit.Percent(percent),
ValueWithUnit.Hour(timeShift).takeIf { timeShift != 0 },
ValueWithUnit.Minute(duration).takeIf { duration != 0 })
treatmentsPlugin.doProfileSwitch(profileStore, profile, duration, percent, timeShift, eventTime)
})
}
return true

View file

@ -71,7 +71,7 @@ class TempBasalDialog : DialogFragmentWithDate() {
?: 100.0, 0.0, maxTempPercent, tempPercentStep, DecimalFormat("0"), true, binding.okcancel.ok)
binding.basalabsoluteinput.setParams(savedInstanceState?.getDouble("basalabsoluteinput")
?: profile.basal, 0.0, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, DecimalFormat("0.00"), true, binding.okcancel.ok)
?: profile.getBasal(), 0.0, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, DecimalFormat("0.00"), true, binding.okcancel.ok)
val tempDurationStep = pumpDescription.tempDurationStep.toDouble()
val tempMaxDuration = pumpDescription.tempMaxDuration.toDouble()

View file

@ -9,7 +9,7 @@ import com.google.common.base.Joiner
import com.google.common.collect.Lists
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.ValueWithUnit
@ -19,6 +19,7 @@ import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
import info.nightscout.androidaps.databinding.DialogTemptargetBinding
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
@ -72,7 +73,7 @@ class TempTargetDialog : DialogFragmentWithDate() {
binding.duration.setParams(savedInstanceState?.getDouble("duration")
?: 0.0, 0.0, Constants.MAX_PROFILE_SWITCH_DURATION, 10.0, DecimalFormat("0"), false, binding.okcancel.ok)
if (profileFunction.getUnits() == Constants.MMOL)
if (profileFunction.getUnits() == GlucoseUnit.MMOL)
binding.temptarget.setParams(
savedInstanceState?.getDouble("tempTarget")
?: 8.0,
@ -84,7 +85,7 @@ class TempTargetDialog : DialogFragmentWithDate() {
Constants.MIN_TT_MGDL, Constants.MAX_TT_MGDL, 1.0, DecimalFormat("0"), false, binding.okcancel.ok)
val units = profileFunction.getUnits()
binding.units.text = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
binding.units.text = if (units == GlucoseUnit.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
// temp target
context?.let { context ->
@ -163,7 +164,7 @@ class TempTargetDialog : DialogFragmentWithDate() {
if (_binding == null) return false
val actions: LinkedList<String> = LinkedList()
var reason = binding.reason.selectedItem?.toString() ?: return false
val unitResId = if (profileFunction.getUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol
val unitResId = if (profileFunction.getUnits() == GlucoseUnit.MGDL) R.string.mgdl else R.string.mmol
val target = binding.temptarget.value
val duration = binding.duration.value.toInt()
if (target != 0.0 && duration != 0) {
@ -181,10 +182,10 @@ class TempTargetDialog : DialogFragmentWithDate() {
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal_temporarytarget), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
val units = profileFunction.getUnits()
when(reason) {
resourceHelper.gs(R.string.eatingsoon) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.EATING_SOON), ValueWithUnit.fromGlucoseUnit(target, units), ValueWithUnit.Minute(duration))
resourceHelper.gs(R.string.activity) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.ACTIVITY), ValueWithUnit.fromGlucoseUnit(target, units), ValueWithUnit.Minute(duration))
resourceHelper.gs(R.string.hypo) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.HYPOGLYCEMIA), ValueWithUnit.fromGlucoseUnit(target, units), ValueWithUnit.Minute(duration))
resourceHelper.gs(R.string.manual) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.CUSTOM), ValueWithUnit.fromGlucoseUnit(target, units), ValueWithUnit.Minute(duration))
resourceHelper.gs(R.string.eatingsoon) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.EATING_SOON), ValueWithUnit.fromGlucoseUnit(target, units.asText), ValueWithUnit.Minute(duration))
resourceHelper.gs(R.string.activity) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.ACTIVITY), ValueWithUnit.fromGlucoseUnit(target, units.asText), ValueWithUnit.Minute(duration))
resourceHelper.gs(R.string.hypo) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.HYPOGLYCEMIA), ValueWithUnit.fromGlucoseUnit(target, units.asText), ValueWithUnit.Minute(duration))
resourceHelper.gs(R.string.manual) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.CUSTOM), ValueWithUnit.fromGlucoseUnit(target, units.asText), ValueWithUnit.Minute(duration))
resourceHelper.gs(R.string.stoptemptarget) -> uel.log(Action.CANCEL_TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged })
}
if (target == 0.0 || duration == 0) {

View file

@ -18,15 +18,11 @@ import dagger.android.HasAndroidInjector
import dagger.android.support.DaggerDialogFragment
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.databinding.DialogWizardBinding
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -38,6 +34,7 @@ import info.nightscout.androidaps.utils.SafeParse
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.extensions.valueToUnits
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -128,7 +125,7 @@ class WizardDialog : DaggerDialogFragment() {
val maxCarbs = constraintChecker.getMaxCarbsAllowed().value()
val maxCorrection = constraintChecker.getMaxBolusAllowed().value()
if (profileFunction.getUnits() == Constants.MGDL)
if (profileFunction.getUnits() == GlucoseUnit.MGDL)
binding.bgInput.setParams(savedInstanceState?.getDouble("bg_input")
?: 0.0, 0.0, 500.0, 1.0, DecimalFormat("0"), false, binding.ok, timeTextWatcher)
else
@ -260,8 +257,8 @@ class WizardDialog : DaggerDialogFragment() {
} ?: return
val units = profileFunction.getUnits()
binding.bgunits.text = units
if (units == Constants.MGDL)
binding.bgunits.text = units.asText
if (units == GlucoseUnit.MGDL)
binding.bgInput.setStep(1.0)
else
binding.bgInput.setStep(0.1)
@ -292,7 +289,7 @@ class WizardDialog : DaggerDialogFragment() {
specificProfile = profileFunction.getProfile()
profileName = profileFunction.getProfileName()
} else
specificProfile = profileStore.getSpecificProfile(profileName)
specificProfile = profileStore.getSpecificProfile(profileName)?.let { ProfileSealed.Pure(it) }
if (specificProfile == null) return
@ -333,7 +330,7 @@ class WizardDialog : DaggerDialogFragment() {
binding.notes.text.toString(), carbTime)
wizard?.let { wizard ->
binding.bg.text = String.format(resourceHelper.gs(R.string.format_bg_isf), valueToUnitsToString(Profile.toMgdl(bg, profileFunction.getUnits()), profileFunction.getUnits()), wizard.sens)
binding.bg.text = String.format(resourceHelper.gs(R.string.format_bg_isf), valueToUnitsToString(Profile.toMgdl(bg, profileFunction.getUnits()), profileFunction.getUnits().asText), wizard.sens)
binding.bginsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBG)
binding.carbs.text = String.format(resourceHelper.gs(R.string.format_carbs_ic), carbs.toDouble(), wizard.ic)

View file

@ -9,7 +9,7 @@ import android.view.WindowManager
import dagger.android.support.DaggerDialogFragment
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.entities.BolusCalculatorResult
import info.nightscout.androidaps.databinding.DialogWizardinfoBinding
import info.nightscout.androidaps.interfaces.ProfileFunction

View file

@ -14,8 +14,10 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.databinding.ActivityHistorybrowseBinding
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.events.EventCustomCalculationFinished
import info.nightscout.androidaps.events.EventRefreshOverview
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
@ -23,14 +25,12 @@ import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.OverviewMenus
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable
@ -50,7 +50,6 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var defaultValueHelper: DefaultValueHelper
@Inject lateinit var iobCobCalculatorPluginHistory: IobCobCalculatorPluginHistory
@Inject lateinit var treatmentsPluginHistory: TreatmentsPluginHistory
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var buildHelper: BuildHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@ -255,7 +254,6 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
private fun runCalculation(from: String) {
lifecycleScope.launch(Dispatchers.Default) {
treatmentsPluginHistory.initializeData(start - T.hours(8).msecs())
val end = start + T.hours(rangeToDisplay.toLong()).msecs()
iobCobCalculatorPluginHistory.stopCalculation(from)
iobCobCalculatorPluginHistory.clearCache()
@ -281,7 +279,7 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
if (destroyed) return@launch
binding.date.text = dateUtil.dateAndTimeString(start)
binding.zoom.text = rangeToDisplay.toString()
val graphData = GraphData(injector, binding.bggraph, iobCobCalculatorPluginHistory, treatmentsPluginHistory)
val graphData = GraphData(injector, binding.bggraph, iobCobCalculatorPluginHistory)
val secondaryGraphsData: ArrayList<GraphData> = ArrayList()
// do preparation in different thread
@ -317,7 +315,7 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
// ------------------ 2nd graph
synchronized(graphLock) {
for (g in 0 until secondaryGraphs.size) {
val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobCalculatorPluginHistory, treatmentsPluginHistory)
val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobCalculatorPluginHistory)
var useIobForScale = false
var useCobForScale = false
var useDevForScale = false

View file

@ -1,48 +0,0 @@
package info.nightscout.androidaps.historyBrowser
import android.content.Context
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.treatments.TreatmentService
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class TreatmentsPluginHistory @Inject constructor(
injector: HasAndroidInjector,
aapsLogger: AAPSLogger,
aapsSchedulers: AapsSchedulers,
rxBus: RxBusWrapper,
resourceHelper: ResourceHelper,
context: Context,
sp: SP,
profileFunction: ProfileFunction,
activePlugin: ActivePlugin,
nsUpload: NSUpload,
fabricPrivacy: FabricPrivacy,
dateUtil: DateUtil,
databaseHelper: DatabaseHelperInterface,
repository: AppRepository
) : TreatmentsPlugin(injector, aapsLogger, rxBus, aapsSchedulers, resourceHelper, context, sp, profileFunction, activePlugin, nsUpload, fabricPrivacy, dateUtil, databaseHelper, repository) {
init {
onStart()
}
override fun onStart() {
service = TreatmentService(injector)
initializeData(range())
}
}

View file

@ -13,7 +13,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.*
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TherapyEvent
@ -292,7 +292,7 @@ open class LoopPlugin @Inject constructor(
if (pump.pumpDescription.tempBasalStyle == PumpDescription.PERCENT && allowPercentage()) {
apsResult.usePercent = true
}
apsResult.percent = (apsResult.rate / profile.basal * 100).toInt()
apsResult.percent = (apsResult.rate / profile.getBasal() * 100).toInt()
// check rate for constraints
val resultAfterConstraints = apsResult.newAndClone(injector)

View file

@ -1,15 +1,15 @@
package info.nightscout.androidaps.plugins.aps.openAPSAMA
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.data.MealData
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.getPassedDurationToTimeInMinutes
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
@ -162,13 +162,13 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader
this.profile.put("max_iob", maxIob)
this.profile.put("dia", min(profile.dia, 3.0))
this.profile.put("type", "current")
this.profile.put("max_daily_basal", profile.maxDailyBasal)
this.profile.put("max_daily_basal", profile.getMaxDailyBasal())
this.profile.put("max_basal", maxBasal)
this.profile.put("min_bg", minBg)
this.profile.put("max_bg", maxBg)
this.profile.put("target_bg", targetBg)
this.profile.put("carb_ratio", profile.ic)
this.profile.put("sens", profile.isfMgdl)
this.profile.put("carb_ratio", profile.getIc())
this.profile.put("sens", profile.getIsfMgdl())
this.profile.put("max_daily_safety_multiplier", sp.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3))
this.profile.put("current_basal_safety_multiplier", sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0))
this.profile.put("skip_neutral_temps", true)
@ -181,7 +181,7 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader
} else {
this.profile.put("min_5m_carbimpact", sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact))
}
if (profileFunction.getUnits() == Constants.MMOL) {
if (profileFunction.getUnits() == GlucoseUnit.MMOL) {
this.profile.put("out_units", "mmol/L")
}
val now = System.currentTimeMillis()

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.aps.openAPSAMA
import android.content.Context
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.interfaces.*
@ -112,9 +112,9 @@ open class OpenAPSAMAPlugin @Inject constructor(
val maxIob = constraintChecker.getMaxIOBAllowed().also { maxIOBAllowedConstraint ->
inputConstraints.copyReasons(maxIOBAllowedConstraint)
}.value()
var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetLowMgdl, 0.1), R.string.profile_low_target, HardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble())
var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetHighMgdl, 0.1), R.string.profile_high_target, HardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble())
var targetBg = hardLimits.verifyHardLimits(profile.targetMgdl, R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble())
var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.getTargetLowMgdl(), 0.1), R.string.profile_low_target, HardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble())
var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.getTargetHighMgdl(), 0.1), R.string.profile_high_target, HardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble())
var targetBg = hardLimits.verifyHardLimits(profile.getTargetMgdl(), R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble())
var isTempTarget = false
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
if (tempTarget is ValueWrapper.Existing) {
@ -125,8 +125,8 @@ open class OpenAPSAMAPlugin @Inject constructor(
}
if (!hardLimits.checkOnlyHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return
if (!hardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return
if (!hardLimits.checkOnlyHardLimits(profile.isfMgdl, R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.maxDailyBasal, R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return
if (!hardLimits.checkOnlyHardLimits(profile.getIsfMgdl(), R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return
if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
startPart = System.currentTimeMillis()
if (constraintChecker.isAutosensModeEnabled().value()) {

View file

@ -1,13 +1,16 @@
package info.nightscout.androidaps.plugins.aps.openAPSSMB
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.data.MealData
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.getPassedDurationToTimeInMinutes
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
@ -17,9 +20,6 @@ import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.utils.SafeParse
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.getPassedDurationToTimeInMinutes
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONArray
@ -180,13 +180,13 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
this.profile.put("max_iob", maxIob)
//mProfile.put("dia", profile.getDia());
this.profile.put("type", "current")
this.profile.put("max_daily_basal", profile.maxDailyBasal)
this.profile.put("max_daily_basal", profile.getMaxDailyBasal())
this.profile.put("max_basal", maxBasal)
this.profile.put("min_bg", minBg)
this.profile.put("max_bg", maxBg)
this.profile.put("target_bg", targetBg)
this.profile.put("carb_ratio", profile.ic)
this.profile.put("sens", profile.isfMgdl)
this.profile.put("carb_ratio", profile.getIc())
this.profile.put("sens", profile.getIsfMgdl())
this.profile.put("max_daily_safety_multiplier", sp.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3))
this.profile.put("current_basal_safety_multiplier", sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0))
@ -225,7 +225,7 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
this.profile.put("current_basal", basalRate)
this.profile.put("temptargetSet", tempTargetSet)
this.profile.put("autosens_max", SafeParse.stringToDouble(sp.getString(R.string.key_openapsama_autosens_max, "1.2")))
if (profileFunction.getUnits() == Constants.MMOL) {
if (profileFunction.getUnits() == GlucoseUnit.MMOL) {
this.profile.put("out_units", "mmol/L")
}
val now = System.currentTimeMillis()

View file

@ -5,9 +5,9 @@ import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.extensions.target
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
@ -22,7 +22,6 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.Profiler
import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.extensions.target
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
@ -118,9 +117,9 @@ open class OpenAPSSMBPlugin @Inject constructor(
inputConstraints.copyReasons(maxIOBAllowedConstraint)
}.value()
var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetLowMgdl, 0.1), R.string.profile_low_target, HardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble())
var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetHighMgdl, 0.1), R.string.profile_high_target, HardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble())
var targetBg = hardLimits.verifyHardLimits(profile.targetMgdl, R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble())
var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.getTargetLowMgdl(), 0.1), R.string.profile_low_target, HardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble())
var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.getTargetHighMgdl(), 0.1), R.string.profile_high_target, HardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble())
var targetBg = hardLimits.verifyHardLimits(profile.getTargetMgdl(), R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble())
var isTempTarget = false
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
if (tempTarget is ValueWrapper.Existing) {
@ -131,8 +130,8 @@ open class OpenAPSSMBPlugin @Inject constructor(
}
if (!hardLimits.checkOnlyHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return
if (!hardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return
if (!hardLimits.checkOnlyHardLimits(profile.isfMgdl, R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.maxDailyBasal, R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return
if (!hardLimits.checkOnlyHardLimits(profile.getIsfMgdl(), R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return
if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
startPart = System.currentTimeMillis()
if (constraintChecker.isAutosensModeEnabled().value()) {

View file

@ -14,7 +14,6 @@ import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.*
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.ConfigImpl
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.util.*
@ -28,7 +27,7 @@ class ObjectivesPlugin @Inject constructor(
resourceHelper: ResourceHelper,
private val activePlugin: ActivePlugin,
private val sp: SP,
config: ConfigImpl,
config: Config,
private val dateUtil: DateUtil,
private val uel: UserEntryLogger
) : PluginBase(PluginDescription()

View file

@ -2,6 +2,8 @@ package info.nightscout.androidaps.plugins.constraints.objectives.objectives
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.PluginBase
@ -9,14 +11,13 @@ import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import javax.inject.Inject
class Objective0(injector: HasAndroidInjector) : Objective(injector, "config", R.string.objectives_0_objective, R.string.objectives_0_gate) {
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var virtualPumpPlugin: VirtualPumpPlugin
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var repository: AppRepository
@Inject lateinit var loopPlugin: LoopPlugin
@Inject lateinit var nsClientPlugin: NSClientPlugin
@Inject lateinit var iobCobCalculator: IobCobCalculator
@ -64,7 +65,7 @@ class Objective0(injector: HasAndroidInjector) : Objective(injector, "config", R
})
tasks.add(object : Task(this, R.string.activate_profile) {
override fun isCompleted(): Boolean {
return treatmentsPlugin.getProfileSwitchFromHistory(dateUtil.now()) != null
return repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing
}
})
}

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.constraints.safety
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
@ -108,18 +108,18 @@ class SafetyPlugin @Inject constructor(
absoluteRate.setIfGreater(aapsLogger, 0.0, String.format(resourceHelper.gs(R.string.limitingbasalratio), 0.0, resourceHelper.gs(R.string.itmustbepositivevalue)), this)
if (config.APS) {
var maxBasal = sp.getDouble(R.string.key_openapsma_max_basal, 1.0)
if (maxBasal < profile.maxDailyBasal) {
maxBasal = profile.maxDailyBasal
if (maxBasal < profile.getMaxDailyBasal()) {
maxBasal = profile.getMaxDailyBasal()
absoluteRate.addReason(resourceHelper.gs(R.string.increasingmaxbasal), this)
}
absoluteRate.setIfSmaller(aapsLogger, maxBasal, String.format(resourceHelper.gs(R.string.limitingbasalratio), maxBasal, resourceHelper.gs(R.string.maxvalueinpreferences)), this)
// Check percentRate but absolute rate too, because we know real current basal in pump
val maxBasalMultiplier = sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0)
val maxFromBasalMultiplier = floor(maxBasalMultiplier * profile.basal * 100) / 100
val maxFromBasalMultiplier = floor(maxBasalMultiplier * profile.getBasal() * 100) / 100
absoluteRate.setIfSmaller(aapsLogger, maxFromBasalMultiplier, String.format(resourceHelper.gs(R.string.limitingbasalratio), maxFromBasalMultiplier, resourceHelper.gs(R.string.maxbasalmultiplier)), this)
val maxBasalFromDaily = sp.getDouble(R.string.key_openapsama_max_daily_safety_multiplier, 3.0)
val maxFromDaily = floor(profile.maxDailyBasal * maxBasalFromDaily * 100) / 100
val maxFromDaily = floor(profile.getMaxDailyBasal() * maxBasalFromDaily * 100) / 100
absoluteRate.setIfSmaller(aapsLogger, maxFromDaily, String.format(resourceHelper.gs(R.string.limitingbasalratio), maxFromDaily, resourceHelper.gs(R.string.maxdailybasalmultiplier)), this)
}
absoluteRate.setIfSmaller(aapsLogger, hardLimits.maxBasal(), String.format(resourceHelper.gs(R.string.limitingbasalratio), hardLimits.maxBasal(), resourceHelper.gs(R.string.hardlimit)), this)
@ -138,7 +138,7 @@ class SafetyPlugin @Inject constructor(
}
override fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> {
val currentBasal = profile.basal
val currentBasal = profile.getBasal()
val absoluteRate = currentBasal * (percentRate.originalValue().toDouble() / 100)
percentRate.addReason("Percent rate " + percentRate.originalValue() + "% recalculated to " + DecimalFormatter.to2Decimal(absoluteRate) + " U/h with current basal " + DecimalFormatter.to2Decimal(currentBasal) + " U/h", this)
val absoluteConstraint = Constraint(absoluteRate)

View file

@ -124,7 +124,7 @@ class DataBroadcastPlugin @Inject constructor(
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("units", profileFunction.getUnits().asText) // 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.shortAvgDelta) // average bg delta
@ -175,7 +175,7 @@ class DataBroadcastPlugin @Inject constructor(
val now = System.currentTimeMillis()
val profile = profileFunction.getProfile() ?: return
bundle.putLong("basalTimeStamp", now)
bundle.putDouble("baseBasal", profile.basal)
bundle.putDouble("baseBasal", profile.getBasal())
bundle.putString("profile", profileFunction.getProfileName())
iobCobCalculator.getTempBasalIncludingConvertedExtended(now)?.let {
bundle.putLong("tempBasalStart", it.timestamp)

View file

@ -35,6 +35,7 @@ class DataSyncSelectorImplementation @Inject constructor(
sp.remove(R.string.key_ns_temporary_basal_last_synced_id)
sp.remove(R.string.key_ns_extended_bolus_last_synced_id)
sp.remove(R.string.key_ns_therapy_event_last_synced_id)
sp.remove(R.string.key_ns_profile_switch_last_synced_id)
}
override fun confirmLastBolusIdIfGreater(lastSynced: Long) {
@ -408,4 +409,40 @@ class DataSyncSelectorImplementation @Inject constructor(
}
return false
}
override fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)) {
aapsLogger.debug(LTag.NSCLIENT, "Setting ProfileSwitch data sync from $lastSynced")
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, lastSynced)
}
}
override fun changedProfileSwitch(): List<ProfileSwitch> {
val startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
return appRepository.getModifiedProfileSwitchDataFromId(startId).blockingGet().also {
aapsLogger.debug(LTag.NSCLIENT, "Loading ProfileSwitch data for sync from $startId. Records ${it.size}")
}
}
override fun processChangedProfileSwitchesCompat(): Boolean {
val startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
appRepository.getNextSyncElementProfileSwitch(startId).blockingGet()?.let { eb ->
aapsLogger.info(LTag.DATABASE, "Loading ProfileSwitch data Start: $startId ID: ${eb.first.id} HistoryID: ${eb.second} ")
when {
// removed and not uploaded yet = ignore
!eb.first.isValid && eb.first.interfaceIDs.nightscoutId == null -> Any()
// removed and already uploaded = send for removal
!eb.first.isValid && eb.first.interfaceIDs.nightscoutId != null ->
nsClientPlugin.nsClientService?.dbRemove("treatments", eb.first.interfaceIDs.nightscoutId, DataSyncSelector.PairProfileSwitch(eb.first, eb.second))
// existing without nsId = create new
eb.first.isValid && eb.first.interfaceIDs.nightscoutId == null ->
nsClientPlugin.nsClientService?.dbAdd("treatments", eb.first.toJson(dateUtil), DataSyncSelector.PairProfileSwitch(eb.first, eb.second))
// existing with nsId = update
eb.first.isValid && eb.first.interfaceIDs.nightscoutId != null ->
nsClientPlugin.nsClientService?.dbUpdate("treatments", eb.first.interfaceIDs.nightscoutId, eb.first.toJson(dateUtil), DataSyncSelector.PairProfileSwitch(eb.first, eb.second))
}
return true
}
return false
}
}

View file

@ -209,6 +209,25 @@ class NSClientAddAckWorker(
dataSyncSelector.processChangedTemporaryBasalsCompat()
}
is PairProfileSwitch -> {
val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id
repository.runTransactionForResult(UpdateNsIdProfileSwitchTransaction(pair.value))
.doOnError { error ->
aapsLogger.error(LTag.DATABASE, "Updated ns id of ProfileSwitch failed", error)
ret = Result.failure((workDataOf("Error" to error.toString())))
}
.doOnSuccess {
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
aapsLogger.debug(LTag.DATABASE, "Updated ns id of ProfileSwitch " + pair.value)
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.updateRecordId)
}
.blockingGet()
rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileSwitch" + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelector.processChangedTemporaryBasalsCompat()
}
is DeviceStatus -> {
val deviceStatus = ack.originalObject
deviceStatus.interfaceIDs.nightscoutId = ack.id

View file

@ -15,7 +15,6 @@ import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.transactions.*
import info.nightscout.androidaps.extensions.*
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
@ -44,7 +43,6 @@ class NSClientAddUpdateWorker(
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var config: Config
@Inject lateinit var repository: AppRepository
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var uel: UserEntryLogger
@ -306,7 +304,29 @@ class NSClientAddUpdateWorker(
}
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json")
eventType == TherapyEvent.Type.PROFILE_SWITCH.text ->
databaseHelper.createProfileSwitchFromJsonIfNotExists(json)
profileSwitchFromJson(json, dateUtil)?.let { profileSwitch ->
repository.runTransactionForResult(SyncNsProfileSwitchTransaction(profileSwitch, invalidateByNsOnly = false))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", it)
ret = Result.failure(workDataOf("Error" to it.toString()))
}
.blockingGet()
.also { result ->
result.inserted.forEach {
uel.log(Action.PROFILE_SWITCH, Sources.NSClient,
ValueWithUnit.Timestamp(it.timestamp))
aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it")
}
result.invalidated.forEach {
uel.log(Action.PROFILE_SWITCH_REMOVED, Sources.NSClient,
ValueWithUnit.Timestamp(it.timestamp))
aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it")
}
result.updatedNsId.forEach {
aapsLogger.debug(LTag.DATABASE, "Updated nsId ProfileSwitch $it")
}
}
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json")
}
if (eventType == TherapyEvent.Type.ANNOUNCEMENT.text) {
val date = safeGetLong(json, "mills")

View file

@ -13,7 +13,6 @@ import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.transactions.*
import info.nightscout.androidaps.extensions.*
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
@ -39,7 +38,6 @@ class NSClientRemoveWorker(
@Inject lateinit var sp: SP
@Inject lateinit var config: Config
@Inject lateinit var repository: AppRepository
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var uel: UserEntryLogger
@ -158,8 +156,20 @@ class NSClientRemoveWorker(
}
}
// old DB model
databaseHelper.deleteProfileSwitchById(nsId)
// room ProfileSwitch
repository.runTransactionForResult(InvalidateNsIdProfileSwitchTransaction(nsId))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while invalidating ProfileSwitch", it)
ret = Result.failure(workDataOf("Error" to it.toString()))
}
.blockingGet()
.also { result ->
result.invalidated.forEach {
uel.log(
Action.CAREPORTAL_REMOVED, Sources.NSClient,
ValueWithUnit.Timestamp(it.timestamp))
}
}
}
return ret

View file

@ -116,6 +116,15 @@ class NSClientUpdateRemoveAckWorker(
dataSyncSelector.processChangedExtendedBolusesCompat()
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
}
is PairProfileSwitch -> {
val pair = ack.originalObject
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.updateRecordId)
rxBus.send(EventNSClientNewLog("DBUPDATE/DBREMOVE", "Acked ProfileSwitch " + ack._id))
// Send new if waiting
dataSyncSelector.processChangedProfileSwitchesCompat()
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
}
}
return ret
}

View file

@ -86,28 +86,6 @@ public class UploadQueue implements UploadQueueAdminInterface {
}
}
@Override
public void removeByNsClientIdIfExists(final JSONObject record) {
startService();
if (NSClientService.handler != null) {
NSClientService.handler.post(() -> {
try {
String id;
if (record.has("NSCLIENT_ID")) {
id = record.getString("NSCLIENT_ID");
} else {
return;
}
if (databaseHelper.deleteDbRequest(id) == 1) {
aapsLogger.debug(LTag.NSCLIENT, "Removed item from UploadQueue. " + status());
}
} catch (JSONException e) {
aapsLogger.error("Unhandled exception", e);
}
});
}
}
@Override
public void removeByMongoId(final String action, final String _id) {
if (_id == null || _id.equals(""))

View file

@ -220,36 +220,18 @@ public class NSClientService extends DaggerService {
public void processAddAck(NSAddAck ack) {
lastAckTime = dateUtil.now();
// new room way
dataWorker.enqueue(
new OneTimeWorkRequest.Builder(NSClientAddAckWorker.class)
.setInputData(dataWorker.storeInputData(ack, null))
.build());
// old way
if (ack.nsClientID != null) {
uploadQueue.removeByNsClientIdIfExists(ack.json);
rxBus.send(new EventNSClientNewLog("DBADD", "Acked " + ack.nsClientID));
} else {
rxBus.send(new EventNSClientNewLog("ERROR", "DBADD Unknown response"));
}
}
public void processUpdateAck(NSUpdateAck ack) {
lastAckTime = dateUtil.now();
// new room way
dataWorker.enqueue(
new OneTimeWorkRequest.Builder(NSClientUpdateRemoveAckWorker.class)
.setInputData(dataWorker.storeInputData(ack, null))
.build());
// old way
if (ack.getResult()) {
uploadQueue.removeByMongoId(ack.getAction(), ack.get_id());
rxBus.send(new EventNSClientNewLog("DBUPDATE/DBREMOVE", "Acked " + ack.get_id()));
} else {
rxBus.send(new EventNSClientNewLog("ERROR", "DBUPDATE/DBREMOVE Unknown response"));
}
}
public void processAuthAck(NSAuthAck ack) {
@ -811,6 +793,7 @@ public class NSClientService extends DaggerService {
dataSyncSelector.processChangedBolusCalculatorResultsCompat();
dataSyncSelector.processChangedTemporaryBasalsCompat();
dataSyncSelector.processChangedExtendedBolusesCompat();
dataSyncSelector.processChangedProfileSwitchesCompat();
dataSyncSelector.processChangedGlucoseValuesCompat();
dataSyncSelector.processChangedTempTargetsCompat();
dataSyncSelector.processChangedFoodsCompat();

View file

@ -222,20 +222,20 @@ class OpenHumansUploader @Inject constructor(
put("isDeletion", deleted)
}
@JvmOverloads
fun enqueueProfileSwitch(profileSwitch: ProfileSwitch, deleted: Boolean = false) = insertQueueItem("ProfileSwitches") {
put("date", profileSwitch.date)
put("isValid", profileSwitch.isValid)
put("source", profileSwitch.source)
put("nsId", profileSwitch._id)
put("isCPP", profileSwitch.isCPP)
put("timeshift", profileSwitch.timeshift)
put("percentage", profileSwitch.percentage)
put("profile", JSONObject(profileSwitch.profileJson))
put("profilePlugin", profileSwitch.profilePlugin)
put("durationInMinutes", profileSwitch.durationInMinutes)
put("isDeletion", deleted)
}
// @JvmOverloads
// fun enqueueProfileSwitch(profileSwitch: ProfileSwitch, deleted: Boolean = false) = insertQueueItem("ProfileSwitches") {
// put("date", profileSwitch.date)
// put("isValid", profileSwitch.isValid)
// put("source", profileSwitch.source)
// put("nsId", profileSwitch._id)
// put("isCPP", profileSwitch.isCPP)
// put("timeshift", profileSwitch.timeshift)
// put("percentage", profileSwitch.percentage)
// put("profile", JSONObject(profileSwitch.profileJson))
// put("profilePlugin", profileSwitch.profilePlugin)
// put("durationInMinutes", profileSwitch.durationInMinutes)
// put("isDeletion", deleted)
// }
// fun enqueueTotalDailyDose(tdd: TDD) = insertQueueItem("TotalDailyDoses") {
// put("double", tdd.date)
@ -368,9 +368,9 @@ class OpenHumansUploader @Inject constructor(
// .andThen(Observable.defer { Observable.fromIterable(databaseHelper.getAllExtendedBoluses()) })
// .map { enqueueExtendedBolus(it); increaseCounter() }
// .ignoreElements()
.andThen(Observable.defer { Observable.fromIterable(databaseHelper.getAllProfileSwitches()) })
.map { enqueueProfileSwitch(it); increaseCounter() }
.ignoreElements()
// .andThen(Observable.defer { Observable.fromIterable(databaseHelper.getAllProfileSwitches()) })
// .map { enqueueProfileSwitch(it); increaseCounter() }
// .ignoreElements()
// .andThen(Observable.defer { Observable.fromIterable(databaseHelper.getAllTDDs()) })
// .map { enqueueTotalDailyDose(it); increaseCounter() }
// .ignoreElements()

View file

@ -27,7 +27,7 @@ import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.TemporaryTarget
@ -256,7 +256,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
.observeOn(aapsSchedulers.io)
.subscribe({ scheduleUpdateGUI("EventAutosensCalculationFinished") }, fabricPrivacy::logException))
disposable.add(rxBus
.toObservable(EventProfileNeedsUpdate::class.java)
.toObservable(EventProfileSwitchChanged::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ scheduleUpdateGUI("EventProfileNeedsUpdate") }, fabricPrivacy::logException))
disposable.add(rxBus
@ -682,29 +682,29 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
if (tempTarget is ValueWrapper.Existing) {
binding.loopPumpStatusLayout.tempTarget.setTextColor(resourceHelper.gc(R.color.ribbonTextWarning))
binding.loopPumpStatusLayout.tempTarget.setBackgroundColor(resourceHelper.gc(R.color.ribbonWarning))
binding.loopPumpStatusLayout.tempTarget.text = Profile.toTargetRangeString(tempTarget.value.lowTarget, tempTarget.value.highTarget, Constants.MGDL, units) + " " + dateUtil.untilString(tempTarget.value.end, resourceHelper)
binding.loopPumpStatusLayout.tempTarget.text = Profile.toTargetRangeString(tempTarget.value.lowTarget, tempTarget.value.highTarget, GlucoseUnit.MGDL, units) + " " + dateUtil.untilString(tempTarget.value.end, resourceHelper)
} else {
// If the target is not the same as set in the profile then oref has overridden it
val targetUsed = lastRun?.constraintsProcessed?.targetBG ?: 0.0
if (targetUsed != 0.0 && abs(profile.targetMgdl - targetUsed) > 0.01) {
aapsLogger.debug("Adjusted target. Profile: ${profile.targetMgdl} APS: $targetUsed")
binding.loopPumpStatusLayout.tempTarget.text = Profile.toTargetRangeString(targetUsed, targetUsed, Constants.MGDL, units)
if (targetUsed != 0.0 && abs(profile.getTargetMgdl() - targetUsed) > 0.01) {
aapsLogger.debug("Adjusted target. Profile: ${profile.getTargetMgdl()} APS: $targetUsed")
binding.loopPumpStatusLayout.tempTarget.text = Profile.toTargetRangeString(targetUsed, targetUsed, GlucoseUnit.MGDL, units)
binding.loopPumpStatusLayout.tempTarget.setTextColor(resourceHelper.gc(R.color.ribbonTextWarning))
binding.loopPumpStatusLayout.tempTarget.setBackgroundColor(resourceHelper.gc(R.color.tempTargetBackground))
} else {
binding.loopPumpStatusLayout.tempTarget.setTextColor(resourceHelper.gc(R.color.ribbonTextDefault))
binding.loopPumpStatusLayout.tempTarget.setBackgroundColor(resourceHelper.gc(R.color.ribbonDefault))
binding.loopPumpStatusLayout.tempTarget.text = Profile.toTargetRangeString(profile.targetLowMgdl, profile.targetHighMgdl, Constants.MGDL, units)
binding.loopPumpStatusLayout.tempTarget.text = Profile.toTargetRangeString(profile.getTargetLowMgdl(), profile.getTargetHighMgdl(), GlucoseUnit.MGDL, units)
}
}
// Basal, TBR
val activeTemp = iobCobCalculator.getTempBasalIncludingConvertedExtended(System.currentTimeMillis())
binding.infoLayout.baseBasal.text = activeTemp?.let { "T:" + activeTemp.toStringShort() }
?: resourceHelper.gs(R.string.pump_basebasalrate, profile.basal)
?: resourceHelper.gs(R.string.pump_basebasalrate, profile.getBasal())
binding.infoLayout.basalLayout.setOnClickListener {
var fullText = "${resourceHelper.gs(R.string.basebasalrate_label)}: ${resourceHelper.gs(R.string.pump_basebasalrate, profile.basal)}"
var fullText = "${resourceHelper.gs(R.string.basebasalrate_label)}: ${resourceHelper.gs(R.string.pump_basebasalrate, profile.getBasal())}"
if (activeTemp != null)
fullText += "\n" + resourceHelper.gs(R.string.tempbasal_label) + ": " + activeTemp.toStringFull(profile, dateUtil)
activity?.let {
@ -734,7 +734,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.infoLayout.extendedLayout.visibility = (extendedBolus is ValueWrapper.Existing && !pump.isFakingTempsByExtendedBoluses).toVisibility()
// Active profile
binding.loopPumpStatusLayout.activeProfile.text = profileFunction.getProfileNameWithDuration()
binding.loopPumpStatusLayout.activeProfile.text = profileFunction.getProfileNameWithRemainingTime()
if (profile.percentage != 100 || profile.timeshift != 0) {
binding.loopPumpStatusLayout.activeProfile.setBackgroundColor(resourceHelper.gc(R.color.ribbonWarning))
binding.loopPumpStatusLayout.activeProfile.setTextColor(resourceHelper.gc(R.color.ribbonTextWarning))
@ -820,7 +820,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
if (_binding == null) return@launch
val menuChartSettings = overviewMenus.setting
prepareGraphsIfNeeded(menuChartSettings.size)
val graphData = GraphData(injector, binding.graphsLayout.bgGraph, iobCobCalculator, treatmentsPlugin)
val graphData = GraphData(injector, binding.graphsLayout.bgGraph, iobCobCalculator)
val secondaryGraphsData: ArrayList<GraphData> = ArrayList()
// do preparation in different thread
@ -888,7 +888,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
// ------------------ 2nd graph
synchronized(graphLock) {
for (g in 0 until min(secondaryGraphs.size, menuChartSettings.size + 1)) {
val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobCalculator, treatmentsPlugin)
val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobCalculator)
var useABSForScale = false
var useIobForScale = false
var useCobForScale = false

View file

@ -9,14 +9,13 @@ import com.jjoe64.graphview.series.DataPoint
import com.jjoe64.graphview.series.LineGraphSeries
import com.jjoe64.graphview.series.Series
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.extensions.target
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
@ -24,7 +23,6 @@ import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.*
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.extensions.target
import info.nightscout.androidaps.utils.resources.ResourceHelper
import java.util.*
import javax.inject.Inject
@ -35,8 +33,7 @@ import kotlin.math.min
class GraphData(
injector: HasAndroidInjector,
private val graph: GraphView,
private val iobCobCalculator: IobCobCalculator,
private val treatmentsPlugin: TreatmentsInterface
private val iobCobCalculator: IobCobCalculator
) {
// IobCobCalculatorPlugin Cannot be injected: HistoryBrowser
@ -53,7 +50,7 @@ class GraphData(
var maxY = Double.MIN_VALUE
private var minY = Double.MAX_VALUE
private var bgReadingsArray: List<GlucoseValue>? = null
private val units: String
private val units: GlucoseUnit
private val series: MutableList<Series<*>> = ArrayList()
init {
@ -80,7 +77,7 @@ class GraphData(
bgReadingsArray = repository.compatGetBgReadingsDataFromTime(fromTime, toTime, false).blockingGet()
if (bgReadingsArray?.isEmpty() != false) {
aapsLogger.debug("No BG data.")
maxY = if (units == Constants.MGDL) 180.0 else 10.0
maxY = if (units == GlucoseUnit.MGDL) 180.0 else 10.0
minY = 0.0
return
}
@ -102,12 +99,8 @@ class GraphData(
addSeries(PointsWithLabelGraphSeries(Array(bgListArray.size) { i -> bgListArray[i] }))
}
internal fun setNumVerticalLabels() {
graph.gridLabelRenderer.numVerticalLabels = if (units == Constants.MGDL) (maxY / 40 + 1).toInt() else (maxY / 2 + 1).toInt()
}
private fun addUpperChartMargin(maxBgValue: Double) =
if (units == Constants.MGDL) Round.roundTo(maxBgValue, 40.0) + 80 else Round.roundTo(maxBgValue, 2.0) + 4
if (units == GlucoseUnit.MGDL) Round.roundTo(maxBgValue, 40.0) + 80 else Round.roundTo(maxBgValue, 2.0) + 4
fun addInRangeArea(fromTime: Long, toTime: Long, lowLine: Double, highLine: Double) {
val inRangeAreaSeries: AreaGraphSeries<DoubleDataPoint>
@ -266,8 +259,8 @@ class GraphData(
}
// ProfileSwitch
treatmentsPlugin.profileSwitchesFromHistory.list
.filterTimeframe(fromTime, endTime)
repository.getEffectiveProfileSwitchDataFromTimeToTime(fromTime, endTime, true).blockingGet()
.map { EffectiveProfileSwitchDataPoint(it) }
.forEach(filteredTreatments::add)
// Extended bolus
@ -282,7 +275,6 @@ class GraphData(
}
// Careportal
// databaseHelper.getCareportalEventsFromTime(fromTime - 6 * 60 * 60 * 1000, true)
repository.compatGetTherapyEventDataFromToTime(fromTime - T.hours(6).msecs(), endTime).blockingGet()
.map { TherapyEventDataPoint(it, resourceHelper, profileFunction, translator) }
.filterTimeframe(fromTime, endTime)
@ -404,12 +396,14 @@ class GraphData(
var time = fromTime
while (time <= toTime) {
val profile = profileFunction.getProfile(time)
if (profile == null) {
time += 5 * 60 * 1000L
continue
}
var iob = 0.0
var absIob = 0.0
if (profile != null) {
iob = iobCobCalculator.calculateFromTreatmentsAndTemps(time, profile).iob
if (absScale) absIob = iobCobCalculator.calculateAbsInsulinFromTreatmentsAndTemps(time).iob
}
if (abs(lastIob - iob) > 0.02) {
if (abs(lastIob - iob) > 0.2) iobArray.add(ScaledDataPoint(time, lastIob, iobScale))
iobArray.add(ScaledDataPoint(time, iob, iobScale))
@ -463,8 +457,12 @@ class GraphData(
var time = fromTime
while (time <= toTime) {
val profile = profileFunction.getProfile(time)
if (profile == null) {
time += 5 * 60 * 1000L
continue
}
var iob = 0.0
if (profile != null) iob = iobCobCalculator.calculateAbsInsulinFromTreatmentsAndTemps(time).iob
iob = iobCobCalculator.calculateAbsInsulinFromTreatmentsAndTemps(time).iob
if (abs(lastIob - iob) > 0.02) {
if (abs(lastIob - iob) > 0.2) iobArray.add(ScaledDataPoint(time, lastIob, iobScale))
iobArray.add(ScaledDataPoint(time, iob, iobScale))
@ -541,7 +539,11 @@ class GraphData(
while (time <= toTime) {
// if align Dev Scale with BGI scale, then calculate BGI value, else bgi = 0.0
val bgi: Double = if (devBgiScale) {
val profile = profileFunction.getProfile(time) ?: continue
val profile = profileFunction.getProfile(time)
if (profile == null) {
time += 5 * 60 * 1000L
continue
}
total = iobCobCalculator.calculateFromTreatmentsAndTemps(time, profile)
total.activity * profile.getIsfMgdl(time) * 5.0
} else 0.0
@ -582,17 +584,10 @@ class GraphData(
val ratioScale = if (useForScale) Scale(100.0) else Scale()
var time = fromTime
while (time <= toTime) {
<<<<<<<<< Temporary merge branch 1
iobCobCalculator.ads.getAutosensDataAtTime(time)?.let { autosensData ->
ratioArray.add(ScaledDataPoint(time, autosensData.autosensResult.ratio - 1, ratioScale))
maxRatioValueFound = max(maxRatioValueFound, autosensData.autosensResult.ratio - 1)
minRatioValueFound = min(minRatioValueFound, autosensData.autosensResult.ratio - 1)
=========
iobCobCalculatorPlugin.getAutosensData(time)?.let { autosensData ->
ratioArray.add(ScaledDataPoint(time, 100.0 * (autosensData.autosensResult.ratio - 1), ratioScale))
maxRatioValueFound = max(maxRatioValueFound, 100.0 * (autosensData.autosensResult.ratio - 1))
minRatioValueFound = min(minRatioValueFound, 100.0 * (autosensData.autosensResult.ratio - 1))
>>>>>>>>> Temporary merge branch 2
}
time += 5 * 60 * 1000L
}
@ -664,6 +659,10 @@ class GraphData(
})
}
fun setNumVerticalLabels() {
graph.gridLabelRenderer.numVerticalLabels = if (units == GlucoseUnit.MGDL) (maxY / 40 + 1).toInt() else (maxY / 2 + 1).toInt()
}
fun formatAxis(fromTime: Long, endTime: Long) {
graph.viewport.setMaxX(endTime.toDouble())
graph.viewport.setMinX(fromTime.toDouble())

View file

@ -0,0 +1,25 @@
package info.nightscout.androidaps.plugins.general.overview.graphExtensions
import android.graphics.Color
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
import javax.inject.Inject
class EffectiveProfileSwitchDataPoint @Inject constructor(
val data: EffectiveProfileSwitch
) : DataPointWithLabelInterface {
private var yValue = 0.0
override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double = yValue
override fun setY(y: Double) {
yValue = y
}
override fun getLabel(): String = data.originalCustomizedName
override fun getDuration(): Long = 0
override fun getShape(): PointsWithLabelGraphSeries.Shape = PointsWithLabelGraphSeries.Shape.PROFILE
override fun getSize(): Float = 10f
override fun getColor(): Int = Color.CYAN
}

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.general.overview.graphExtensions
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -15,8 +16,8 @@ class GlucoseValueDataPoint @Inject constructor(
private val resourceHelper: ResourceHelper
) : DataPointWithLabelInterface {
fun valueToUnits(units: String): Double =
if (units == Constants.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL
fun valueToUnits(units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL
override fun getX(): Double {
return data.timestamp.toDouble()

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.general.overview.graphExtensions
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.data.InMemoryGlucoseValue
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
@ -13,8 +14,8 @@ class InMemoryGlucoseValueDataPoint @Inject constructor(
private val resourceHelper: ResourceHelper
) : DataPointWithLabelInterface {
fun valueToUnits(units: String): Double =
if (units == Constants.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL
fun valueToUnits(units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL
override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double = valueToUnits(profileFunction.getUnits())

View file

@ -3,8 +3,9 @@ package info.nightscout.androidaps.plugins.general.overview.graphExtensions
import android.graphics.Color
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.Interval
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.utils.Translator
@ -30,11 +31,11 @@ class TherapyEventDataPoint @Inject constructor(
if (data.glucose != null && data.glucose != 0.0) {
var mmol = 0.0
var mgdl = 0.0
if (units == Constants.MGDL) {
if (units == GlucoseUnit.MGDL) {
mgdl = data.glucose!!
mmol = data.glucose!! * Constants.MGDL_TO_MMOLL
}
if (units == Constants.MMOL) {
if (units == GlucoseUnit.MMOL) {
mmol = data.glucose!!
mgdl = data.glucose!! * Constants.MMOLL_TO_MGDL
}

View file

@ -10,7 +10,7 @@ import androidx.core.app.RemoteInput
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.events.*
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger

View file

@ -15,7 +15,7 @@ import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.entities.TemporaryTarget
@ -584,7 +584,7 @@ class SmsCommunicatorPlugin @Inject constructor(
val finalPercentage = percentage
messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(list[pIndex - 1] as String, finalPercentage) {
override fun run() {
activePlugin.activeTreatments.doProfileSwitch(store, list[pIndex - 1] as String, 0, finalPercentage, 0, dateUtil.now())
profileFunction.createProfileSwitch(store, list[pIndex - 1] as String, 0, finalPercentage, 0, dateUtil.now())
val replyText = resourceHelper.gs(R.string.profileswitchcreated)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
uel.log(Action.PROFILE_SWITCH, Sources.SMS, resourceHelper.gs(R.string.profileswitchcreated),
@ -817,11 +817,11 @@ class SmsCommunicatorPlugin @Inject constructor(
eatingSoonTTDuration =
if (eatingSoonTTDuration > 0) eatingSoonTTDuration
else Constants.defaultEatingSoonTTDuration
var eatingSoonTT = sp.getDouble(R.string.key_eatingsoon_target, if (currentProfile.units == Constants.MMOL) Constants.defaultEatingSoonTTmmol else Constants.defaultEatingSoonTTmgdl)
var eatingSoonTT = sp.getDouble(R.string.key_eatingsoon_target, if (currentProfile.units == GlucoseUnit.MMOL) Constants.defaultEatingSoonTTmmol else Constants.defaultEatingSoonTTmgdl)
eatingSoonTT =
when {
eatingSoonTT > 0 -> eatingSoonTT
currentProfile.units == Constants.MMOL -> Constants.defaultEatingSoonTTmmol
currentProfile.units == GlucoseUnit.MMOL -> Constants.defaultEatingSoonTTmmol
else -> Constants.defaultEatingSoonTTmgdl
}
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
@ -836,7 +836,7 @@ class SmsCommunicatorPlugin @Inject constructor(
}, {
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
})
val tt = if (currentProfile.units == Constants.MMOL) {
val tt = if (currentProfile.units == GlucoseUnit.MMOL) {
DecimalFormatter.to1Decimal(eatingSoonTT)
} else DecimalFormatter.to0Decimal(eatingSoonTT)
replyText += "\n" + String.format(resourceHelper.gs(R.string.smscommunicator_mealbolusdelivered_tt), tt, eatingSoonTTDuration)
@ -863,7 +863,7 @@ class SmsCommunicatorPlugin @Inject constructor(
private fun toTodayTime(hh_colon_mm: String): Long {
val p = Pattern.compile("(\\d+):(\\d+)( a.m.| p.m.| AM| PM|AM|PM|)")
val m = p.matcher(hh_colon_mm)
var retval: Long = 0
var retVal: Long = 0
if (m.find()) {
var hours = SafeParse.stringToInt(m.group(1))
val minutes = SafeParse.stringToInt(m.group(2))
@ -874,9 +874,9 @@ class SmsCommunicatorPlugin @Inject constructor(
.withMinuteOfHour(minutes)
.withSecondOfMinute(0)
.withMillisOfSecond(0)
retval = t.millis
retVal = t.millis
}
return retval
return retVal
}
private fun processCARBS(divided: Array<String>, receivedSms: Sms) {
@ -966,9 +966,9 @@ class SmsCommunicatorPlugin @Inject constructor(
}
var ttDuration = sp.getInt(keyDuration, defaultTargetDuration)
ttDuration = if (ttDuration > 0) ttDuration else defaultTargetDuration
var tt = sp.getDouble(keyTarget, if (units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL)
var tt = sp.getDouble(keyTarget, if (units == GlucoseUnit.MMOL) defaultTargetMMOL else defaultTargetMGDL)
tt = Profile.toCurrentUnits(profileFunction, tt)
tt = if (tt > 0) tt else if (units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL
tt = if (tt > 0) tt else if (units == GlucoseUnit.MMOL) defaultTargetMMOL else defaultTargetMGDL
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
timestamp = dateUtil.now(),
duration = TimeUnit.MINUTES.toMillis(ttDuration.toLong()),
@ -981,11 +981,11 @@ class SmsCommunicatorPlugin @Inject constructor(
}, {
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
})
val ttString = if (units == Constants.MMOL) DecimalFormatter.to1Decimal(tt) else DecimalFormatter.to0Decimal(tt)
val ttString = if (units == GlucoseUnit.MMOL) DecimalFormatter.to1Decimal(tt) else DecimalFormatter.to0Decimal(tt)
val replyText = String.format(resourceHelper.gs(R.string.smscommunicator_tt_set), ttString, ttDuration)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
uel.log(Action.TT, Sources.SMS,
ValueWithUnit.fromGlucoseUnit(tt, units),
ValueWithUnit.fromGlucoseUnit(tt, units.asText),
ValueWithUnit.Minute(ttDuration))
}
})

View file

@ -2,10 +2,9 @@ package info.nightscout.androidaps.plugins.general.tidepool.comm
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
import info.nightscout.androidaps.database.entities.TemporaryBasal
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
@ -29,7 +28,6 @@ class UploadChunk @Inject constructor(
private val aapsLogger: AAPSLogger,
private val profileFunction: ProfileFunction,
private val activePlugin: ActivePlugin,
private val databaseHelper: DatabaseHelperInterface,
private val repository: AppRepository,
private val dateUtil: DateUtil
) {
@ -162,14 +160,14 @@ class UploadChunk @Inject constructor(
return selection
}
private fun newInstanceOrNull(ps: ProfileSwitch): ProfileElement? = try {
private fun newInstanceOrNull(ps: EffectiveProfileSwitch): ProfileElement? = try {
ProfileElement(ps, activePlugin.activePump.serialNumber(), dateUtil)
} catch (e: Throwable) {
null
}
private fun getProfiles(start: Long, end: Long): List<ProfileElement> {
val pss = databaseHelper.getProfileSwitchEventsFromTime(start, end, true)
val pss = repository.getEffectiveProfileSwitchDataFromTimeToTime(start, end, true).blockingGet()
val selection = LinkedList<ProfileElement>()
for (ps in pss) {
newInstanceOrNull(ps)?.let { selection.add(it) }

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.entities.TemporaryBasal
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.utils.DateUtil

View file

@ -1,9 +1,10 @@
package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.extensions.toConstant
import info.nightscout.androidaps.extensions.toMainUnit
import info.nightscout.androidaps.utils.DateUtil
import java.util.*
@ -23,7 +24,7 @@ class BloodGlucoseElement(therapyEvent: TherapyEvent, dateUtil: DateUtil)
type = "cbg"
subType = "manual" // TODO
value = if (therapyEvent.glucose != null)
Profile.toMgdl(therapyEvent.glucose!!, therapyEvent.glucoseUnit.toConstant()).toInt()
Profile.toMgdl(therapyEvent.glucose!!, therapyEvent.glucoseUnit.toMainUnit()).toInt()
else 0
}

View file

@ -1,15 +1,16 @@
package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.plugins.general.tidepool.comm.TidepoolUploader
import info.nightscout.androidaps.utils.DateUtil
import java.util.*
import kotlin.collections.ArrayList
class ProfileElement(ps: ProfileSwitch, serialNumber: String, dateUtil: DateUtil)
: BaseElement(ps.date, UUID.nameUUIDFromBytes(("AAPS-profile" + ps.date).toByteArray()).toString(), dateUtil) {
class ProfileElement(ps: EffectiveProfileSwitch, serialNumber: String, dateUtil: DateUtil)
: BaseElement(ps.timestamp, UUID.nameUUIDFromBytes(("AAPS-profile" + ps.timestamp).toByteArray()).toString(), dateUtil) {
@Expose
internal var activeSchedule = "Normal"
@ -34,15 +35,15 @@ class ProfileElement(ps: ProfileSwitch, serialNumber: String, dateUtil: DateUtil
init {
type = "pumpSettings"
val profile: Profile? = ps.profileObject
val profile: Profile? = ProfileSealed.EPS(ps)
checkNotNull(profile)
for (br in profile.basalValues)
for (br in profile.getBasalValues())
basalSchedules.Normal.add(BasalRate(br.timeAsSeconds * 1000, br.value))
for (target in profile.singleTargetsMgdl)
for (target in profile.getSingleTargetsMgdl())
bgTargets.Normal.add(Target(target.timeAsSeconds * 1000, target.value))
for (ic in profile.ics)
for (ic in profile.getIcsValues())
carbRatios.Normal.add(Ratio(ic.timeAsSeconds * 1000, ic.value))
for (isf in profile.isfsMgdl)
for (isf in profile.getIsfsMgdlValues())
insulinSensitivities.Normal.add(Ratio(isf.timeAsSeconds * 1000, isf.value))
}

View file

@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.general.wear
import android.app.NotificationManager
import android.content.Context
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.dana.DanaPump
@ -12,7 +11,6 @@ import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.androidaps.danars.DanaRSPlugin
import info.nightscout.androidaps.data.DetailedBolusInfo
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
@ -146,7 +144,7 @@ class ActionStringHandler @Inject constructor(
rAction += "bolus $insulinAfterConstraints $carbsAfterConstraints"
} else if ("temptarget" == act[0]) { ///////////////////////////////////////////////////////// TEMPTARGET
val isMGDL = java.lang.Boolean.parseBoolean(act[1])
if (profileFunction.getUnits() == Constants.MGDL != isMGDL) {
if (profileFunction.getUnits() == GlucoseUnit.MGDL != isMGDL) {
sendError("Different units used on watch and phone!")
return
}
@ -251,25 +249,25 @@ class ActionStringHandler @Inject constructor(
}
lastBolusWizard = bolusWizard
} else if ("opencpp" == act[0]) {
val activeProfileSwitch = activePlugin.activeTreatments.getProfileSwitchFromHistory(System.currentTimeMillis())
if (activeProfileSwitch == null) {
sendError("No active profile switch!")
return
} else { // read CPP values
val activeProfileSwitch = repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet()
if (activeProfileSwitch is ValueWrapper.Existing) { // read CPP values
rTitle = "opencpp"
rMessage = "opencpp"
rAction = "opencpp" + " " + activeProfileSwitch.percentage + " " + activeProfileSwitch.timeshift
}
} else if ("cppset" == act[0]) {
val activeProfileSwitch = activePlugin.activeTreatments.getProfileSwitchFromHistory(System.currentTimeMillis())
if (activeProfileSwitch == null) {
rAction = "opencpp" + " " + activeProfileSwitch.value.originalPercentage + " " + activeProfileSwitch.value.originalTimeshift
} else {
sendError("No active profile switch!")
return
} else { // read CPP values
}
} else if ("cppset" == act[0]) {
val activeProfileSwitch = repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet()
if (activeProfileSwitch is ValueWrapper.Existing) {
rMessage = "CPP:" + "\n\n" +
"Timeshift: " + act[1] + "\n" +
"Percentage: " + act[2] + "%"
rAction = actionString
} else { // read CPP values
sendError("No active profile switch!")
return
}
} else if ("tddstats" == act[0]) {
val activePump = activePlugin.activePump
@ -456,13 +454,13 @@ class ActionStringHandler @Inject constructor(
//Check for Temp-Target:
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
if (tempTarget is ValueWrapper.Existing) {
ret += "Temp Target: " + Profile.toTargetRangeString(tempTarget.value.lowTarget, tempTarget.value.lowTarget, Constants.MGDL, profileFunction.getUnits())
ret += "Temp Target: " + Profile.toTargetRangeString(tempTarget.value.lowTarget, tempTarget.value.lowTarget, GlucoseUnit.MGDL, profileFunction.getUnits())
ret += "\nuntil: " + dateUtil.timeString(tempTarget.value.end)
ret += "\n\n"
}
ret += "DEFAULT RANGE: "
ret += Profile.fromMgdlToUnits(profile.targetLowMgdl, profileFunction.getUnits()).toString() + " - " + Profile.fromMgdlToUnits(profile.targetHighMgdl, profileFunction.getUnits())
ret += " target: " + Profile.fromMgdlToUnits(profile.targetMgdl, profileFunction.getUnits())
ret += Profile.fromMgdlToUnits(profile.getTargetLowMgdl(), profileFunction.getUnits()).toString() + " - " + Profile.fromMgdlToUnits(profile.getTargetHighMgdl(), profileFunction.getUnits())
ret += " target: " + Profile.fromMgdlToUnits(profile.getTargetMgdl(), profileFunction.getUnits())
return ret
}
@ -569,7 +567,7 @@ class ActionStringHandler @Inject constructor(
uel.log(Action.PROFILE_SWITCH, Sources.Wear,
ValueWithUnit.Percent(percentage),
ValueWithUnit.Hour(timeshift).takeIf { timeshift != 0 })
activePlugin.activeTreatments.doProfileSwitch(0, percentage, timeshift)
profileFunction.createProfileSwitch(0, percentage, timeshift)
}
private fun generateTempTarget(duration: Int, low: Double, high: Double) {
@ -588,8 +586,8 @@ class ActionStringHandler @Inject constructor(
})
uel.log(Action.TT, Sources.Wear,
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.WEAR),
ValueWithUnit.fromGlucoseUnit(low, profileFunction.getUnits()),
ValueWithUnit.fromGlucoseUnit(high, profileFunction.getUnits()).takeIf { low != high },
ValueWithUnit.fromGlucoseUnit(low, profileFunction.getUnits().asText),
ValueWithUnit.fromGlucoseUnit(high, profileFunction.getUnits().asText).takeIf { low != high },
ValueWithUnit.Minute(duration))
} else {
disposable += repository.runTransactionForResult(CancelCurrentTemporaryTargetIfAnyTransaction(System.currentTimeMillis()))

View file

@ -33,7 +33,8 @@ import info.nightscout.androidaps.interfaces.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.GlucoseUnit;
import info.nightscout.androidaps.interfaces.Profile;
import info.nightscout.androidaps.database.AppRepository;
import info.nightscout.androidaps.database.entities.Bolus;
import info.nightscout.androidaps.database.entities.GlucoseValue;
@ -298,9 +299,9 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
private DataMap dataMapSingleBG(GlucoseValue lastBG, GlucoseStatus glucoseStatus) {
String units = profileFunction.getUnits();
GlucoseUnit units = profileFunction.getUnits();
double convert2MGDL = 1.0;
if (units.equals(Constants.MMOL))
if (units.equals(GlucoseUnit.MMOL))
convert2MGDL = Constants.MMOLL_TO_MGDL;
double lowLine = defaultValueHelper.determineLowLine() * convert2MGDL;
double highLine = defaultValueHelper.determineHighLine() * convert2MGDL;
@ -314,7 +315,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
DataMap dataMap = new DataMap();
dataMap.putString("sgvString", GlucoseValueExtensionKt.valueToUnitsString(lastBG, units));
dataMap.putString("glucoseUnits", units);
dataMap.putString("glucoseUnits", units.getAsText());
dataMap.putLong("timestamp", lastBG.getTimestamp());
if (glucoseStatus == null) {
dataMap.putString("slopeArrow", "");
@ -332,7 +333,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
return dataMap;
}
private String deltastring(double deltaMGDL, double deltaMMOL, String units) {
private String deltastring(double deltaMGDL, double deltaMMOL, GlucoseUnit units) {
String deltastring = "";
if (deltaMGDL >= 0) {
deltastring += "+";
@ -341,7 +342,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
}
boolean detailed = sp.getBoolean(R.string.key_wear_detailed_delta, false);
if (units.equals(Constants.MGDL)) {
if (units.equals(GlucoseUnit.MGDL)) {
if (detailed) {
deltastring += DecimalFormatter.INSTANCE.to1Decimal(Math.abs(deltaMGDL));
} else {
@ -541,7 +542,6 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
.collect(Collectors.toList());
if (!predArray.isEmpty()) {
final String units = profileFunction.getUnits();
for (GlucoseValueDataPoint bg : predArray) {
if (bg.getData().getValue() < 40) continue;
predictions.add(predictionMap(bg.getData().getTimestamp(), bg.getData().getValue(), bg.getPredictionColor()));
@ -695,7 +695,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
currentBasal = generateBasalString();
//bgi
double bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.fromMgdlToUnits(profile.getIsfMgdl(), profileFunction.getUnits());
double bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.Companion.fromMgdlToUnits(profile.getIsfMgdl(), profileFunction.getUnits());
bgiString = "" + ((bgi >= 0) ? "+" : "") + DecimalFormatter.INSTANCE.to1Decimal(bgi);
status = generateStatusString(profile, currentBasal, iobSum, iobDetail, bgiString);

View file

@ -5,15 +5,14 @@ import android.content.Intent
import android.os.Bundle
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.events.*
import info.nightscout.androidaps.extensions.toStringShort
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.extensions.toStringShort
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -31,7 +30,6 @@ class StatusLinePlugin @Inject constructor(
private val aapsSchedulers: AapsSchedulers,
private val context: Context,
private val fabricPrivacy: FabricPrivacy,
private val activePlugin: ActivePlugin,
private val loopPlugin: LoopPlugin,
private val iobCobCalculator: IobCobCalculator,
private val rxBus: RxBusWrapper,
@ -136,7 +134,7 @@ class StatusLinePlugin @Inject constructor(
+ DecimalFormatter.to2Decimal(basalIob.basaliob) + ")")
}
if (sp.getBoolean(R.string.key_xdripstatus_showbgi, true)) {
val bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.fromMgdlToUnits(profile.isfMgdl, profileFunction.getUnits())
val bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.fromMgdlToUnits(profile.getIsfMgdl(), profileFunction.getUnits())
status += " " + (if (bgi >= 0) "+" else "") + DecimalFormatter.to2Decimal(bgi)
}
// COB

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.insulin
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Iob
import info.nightscout.androidaps.database.embedments.InsulinConfiguration
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.interfaces.Insulin
import info.nightscout.androidaps.interfaces.PluginBase
@ -13,6 +14,7 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
import kotlin.math.exp
import kotlin.math.pow
@ -86,6 +88,9 @@ abstract class InsulinOrefBasePlugin(
return result
}
override val insulinConfiguration: InsulinConfiguration
get() = InsulinConfiguration(friendlyName, (dia * 1000.0 * 3600.0).toLong(), T.mins(peak.toLong()).msecs())
override val comment
get(): String {
var comment = commentStandardText()

View file

@ -7,7 +7,7 @@ import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.data.MealData
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.Bolus
@ -150,6 +150,8 @@ open class IobCobCalculatorPlugin @Inject constructor(
if (oldestBolus != null) oldestTime = min(oldestTime, oldestBolus.timestamp)
val oldestCarbs = repository.getOldestCarbsRecord()
if (oldestCarbs != null) oldestTime = min(oldestTime, oldestCarbs.timestamp)
val oldestPs = repository.getOldestEffectiveProfileSwitchRecord()
if (oldestPs != null) oldestTime = min(oldestTime, oldestPs.timestamp)
oldestTime -= 15 * 60 * 1000L // allow 15 min before
return oldestTime
}

View file

@ -117,7 +117,7 @@ class IobCobOref1Thread internal constructor(
val profile = profileFunction.getProfile(bgTime)
if (profile == null) {
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (no profile): $from")
return // profile not set yet
continue // profile not set yet
}
aapsLogger.debug(LTag.AUTOSENS, "Processing calculation thread: " + from + " (" + i + "/" + bucketedData.size + ")")
val sens = profile.getIsfMgdl(bgTime)

View file

@ -116,7 +116,7 @@ class IobCobThread @Inject internal constructor(
val profile = profileFunction.getProfile(bgTime)
if (profile == null) {
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (no profile): $from")
return // profile not set yet
continue // profile not set yet
}
aapsLogger.debug(LTag.AUTOSENS, "Processing calculation thread: " + from + " (" + i + "/" + bucketedData.size + ")")
val sens = profile.getIsfMgdl(bgTime)

View file

@ -11,13 +11,15 @@ import android.widget.ArrayAdapter
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.databinding.LocalprofileFragmentBinding
import info.nightscout.androidaps.dialogs.ProfileSwitchDialog
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -66,7 +68,7 @@ class LocalProfileFragment : DaggerFragment() {
private fun sumLabel(): String {
val profile = localProfilePlugin.createProfileStore().getDefaultProfile()
val sum = profile?.baseBasalSum() ?: 0.0
val sum = profile?.let { ProfileSealed.Pure(profile).baseBasalSum() } ?: 0.0
return "" + DecimalFormatter.to2Decimal(sum) + resourceHelper.gs(R.string.insulin_unit_shortname)
}
@ -127,8 +129,8 @@ class LocalProfileFragment : DaggerFragment() {
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, HardLimits.MIN_ISF, HardLimits.MAX_ISF, 1.0, DecimalFormat("0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), 1.0, DecimalFormat("0"), save)
} else {
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, Profile.fromMgdlToUnits(HardLimits.MIN_ISF, Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.MAX_ISF, Constants.MMOL), 0.1, DecimalFormat("0.0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), Constants.MMOL), 0.1, DecimalFormat("0.0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, Profile.fromMgdlToUnits(HardLimits.MIN_ISF, GlucoseUnit.MMOL), Profile.fromMgdlToUnits(HardLimits.MAX_ISF, GlucoseUnit.MMOL), 0.1, DecimalFormat("0.0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), GlucoseUnit.MMOL), Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), GlucoseUnit.MMOL), 0.1, DecimalFormat("0.0"), save)
}
// Spinner
@ -175,7 +177,8 @@ class LocalProfileFragment : DaggerFragment() {
if (localProfilePlugin.isEdited) {
activity?.let { OKDialog.show(it, "", resourceHelper.gs(R.string.saveorresetchangesfirst)) }
} else {
uel.log(Action.CLONE_PROFILE, Sources.LocalProfile, ValueWithUnit.SimpleString(localProfilePlugin.currentProfile()?.name ?: ""))
uel.log(Action.CLONE_PROFILE, Sources.LocalProfile, ValueWithUnit.SimpleString(localProfilePlugin.currentProfile()?.name
?: ""))
localProfilePlugin.cloneProfile()
build()
}
@ -184,7 +187,8 @@ class LocalProfileFragment : DaggerFragment() {
binding.profileRemove.setOnClickListener {
activity?.let { activity ->
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.deletecurrentprofile), {
uel.log(Action.PROFILE_REMOVED, Sources.LocalProfile, ValueWithUnit.SimpleString(localProfilePlugin.currentProfile()?.name ?: ""))
uel.log(Action.PROFILE_REMOVED, Sources.LocalProfile, ValueWithUnit.SimpleString(localProfilePlugin.currentProfile()?.name
?: ""))
localProfilePlugin.removeCurrentProfile()
build()
}, null)
@ -212,7 +216,8 @@ class LocalProfileFragment : DaggerFragment() {
if (!localProfilePlugin.isValidEditState()) {
return@setOnClickListener //Should not happen as saveButton should not be visible if not valid
}
uel.log(Action.STORE_PROFILE, Sources.LocalProfile, ValueWithUnit.SimpleString(localProfilePlugin.currentProfile()?.name ?: ""))
uel.log(Action.STORE_PROFILE, Sources.LocalProfile, ValueWithUnit.SimpleString(localProfilePlugin.currentProfile()?.name
?: ""))
localProfilePlugin.storeSettings(activity)
build()
}

View file

@ -4,8 +4,10 @@ import androidx.fragment.app.FragmentActivity
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.data.PureProfile
import info.nightscout.androidaps.events.EventProfileStoreChanged
import info.nightscout.androidaps.extensions.blockFromJsonArray
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
@ -13,6 +15,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -33,6 +36,8 @@ class LocalProfilePlugin @Inject constructor(
private val sp: SP,
private val profileFunction: ProfileFunction,
private val nsUpload: NSUpload,
private val activePlugin: ActivePlugin,
private val hardLimits: HardLimits,
private val dateUtil: DateUtil
) : PluginBase(PluginDescription()
.mainType(PluginType.PROFILE)
@ -91,8 +96,25 @@ class LocalProfilePlugin @Inject constructor(
@Synchronized
fun isValidEditState(): Boolean {
return createProfileStore().getDefaultProfile()?.isValid(resourceHelper.gs(R.string.localprofile), false)
?: false
val pumpDescription = activePlugin.activePump.pumpDescription
with(profiles[currentProfileIndex]) {
if (dia < hardLimits.minDia() || dia > hardLimits.maxDia()) return false
if (name.isNullOrEmpty()) return false
if (blockFromJsonArray(ic, dateUtil)?.any { it.amount < hardLimits.minIC() || it.amount > hardLimits.maxIC() } != false) return false
if (blockFromJsonArray(isf, dateUtil)?.any { it.amount < HardLimits.MIN_ISF || it.amount > HardLimits.MAX_ISF } != false) return false
if (blockFromJsonArray(basal, dateUtil)?.any { it.amount < pumpDescription.basalMinimumRate || it.amount > 10.0 } != false) return false
val low = blockFromJsonArray(targetLow, dateUtil)
val high = blockFromJsonArray(targetHigh, dateUtil)
if (profileFunction.getUnits() == GlucoseUnit.MGDL) {
if (low?.any { it.amount < HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble() || it.amount > HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble() } != false) return false
if (high?.any { it.amount < HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble() || it.amount > HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble() } != false) return false
} else {
if (low?.any { it.amount < Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), GlucoseUnit.MMOL) || it.amount > Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), GlucoseUnit.MMOL) } != false) return false
if (high?.any { it.amount < Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), GlucoseUnit.MMOL) || it.amount > Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), GlucoseUnit.MMOL) } != false) return false
}
for (i in low.indices) if (low[i].amount > high[i].amount) return false
}
return true
}
@Synchronized
@ -200,20 +222,22 @@ class LocalProfilePlugin @Inject constructor(
createAndStoreConvertedProfile()
}
fun copyFrom(profile: Profile, newName: String): SingleProfile {
fun copyFrom(pureProfile: PureProfile, newName: String): SingleProfile {
var verifiedName = newName
if (rawProfile?.getSpecificProfile(newName) != null) {
verifiedName += " " + dateUtil.now().toString()
}
val profile = ProfileSealed.Pure(pureProfile)
val pureJson = pureProfile.jsonObject
val sp = SingleProfile()
sp.name = verifiedName
sp.mgdl = profile.units == Constants.MGDL
sp.dia = profile.dia
sp.ic = JSONArray(profile.data.getJSONArray("carbratio").toString())
sp.isf = JSONArray(profile.data.getJSONArray("sens").toString())
sp.basal = JSONArray(profile.data.getJSONArray("basal").toString())
sp.targetLow = JSONArray(profile.data.getJSONArray("target_low").toString())
sp.targetHigh = JSONArray(profile.data.getJSONArray("target_high").toString())
sp.mgdl = profile.units == GlucoseUnit.MGDL
sp.dia = pureJson.getDouble("dia")
sp.ic = pureJson.getJSONArray("carbratio")
sp.isf = pureJson.getJSONArray("sens")
sp.basal = pureJson.getJSONArray("basal")
sp.targetLow = pureJson.getJSONArray("target_low")
sp.targetHigh = pureJson.getJSONArray("target_high")
return sp
}
@ -276,7 +300,7 @@ class LocalProfilePlugin @Inject constructor(
}
val p = SingleProfile()
p.name = Constants.LOCAL_PROFILE + free
p.mgdl = profileFunction.getUnits() == Constants.MGDL
p.mgdl = profileFunction.getUnits() == GlucoseUnit.MGDL
p.dia = Constants.defaultDIA
p.ic = JSONArray(defaultArray)
p.isf = JSONArray(defaultArray)
@ -346,13 +370,14 @@ class LocalProfilePlugin @Inject constructor(
aapsLogger.error("Unhandled exception", e)
}
return ProfileStore(injector, json)
return ProfileStore(injector, json, dateUtil)
}
override val profile: ProfileStore?
get() = rawProfile
override val profileName: String
get() = DecimalFormatter.to2Decimal(rawProfile?.getDefaultProfile()?.percentageBasalSum()
?: 0.0) + "U "
get() = rawProfile?.getDefaultProfile()?.let {
DecimalFormatter.to2Decimal(ProfileSealed.Pure(it).percentageBasalSum()) + "U "
} ?: "INVALID"
}

View file

@ -8,28 +8,29 @@ import android.widget.AdapterView
import android.widget.ArrayAdapter
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.databinding.NsprofileFragmentBinding
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.profile.ns.events.EventNSProfileUpdateGUI
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import io.reactivex.rxkotlin.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import javax.inject.Inject
class NSProfileFragment : DaggerFragment() {
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@ -38,6 +39,8 @@ class NSProfileFragment : DaggerFragment() {
@Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var config: Config
private var disposable: CompositeDisposable = CompositeDisposable()
@ -68,7 +71,7 @@ class NSProfileFragment : DaggerFragment() {
uel.log(Action.PROFILE_SWITCH, Sources.NSProfile,
ValueWithUnit.SimpleString(name),
ValueWithUnit.Percent(100))
treatmentsPlugin.doProfileSwitch(store, name, 0, 100, 0, dateUtil.now())
profileFunction.createProfileSwitch(store, name, 0, 100, 0, dateUtil.now())
})
}
}
@ -100,16 +103,17 @@ class NSProfileFragment : DaggerFragment() {
nsProfilePlugin.profile?.let { store ->
store.getSpecificProfile(name)?.let { profile ->
if (_binding == null) return
binding.profileviewer.units.text = profile.units
binding.profileviewer.dia.text = resourceHelper.gs(R.string.format_hours, profile.dia)
val pss = ProfileSealed.Pure(profile)
binding.profileviewer.units.text = pss.units.asText
binding.profileviewer.dia.text = resourceHelper.gs(R.string.format_hours, pss.dia)
binding.profileviewer.activeprofile.text = name
binding.profileviewer.ic.text = profile.icList
binding.profileviewer.isf.text = profile.isfList
binding.profileviewer.basal.text = profile.basalList
binding.profileviewer.basaltotal.text = String.format(resourceHelper.gs(R.string.profile_total), DecimalFormatter.to2Decimal(profile.baseBasalSum()))
binding.profileviewer.target.text = profile.targetList
binding.profileviewer.basalGraph.show(profile)
if (profile.isValid("NSProfileFragment")) {
binding.profileviewer.ic.text = pss.getIcList(resourceHelper, dateUtil)
binding.profileviewer.isf.text = pss.getIsfList(resourceHelper, dateUtil)
binding.profileviewer.basal.text = pss.getBasalList(resourceHelper, dateUtil)
binding.profileviewer.basaltotal.text = String.format(resourceHelper.gs(R.string.profile_total), DecimalFormatter.to2Decimal(pss.baseBasalSum()))
binding.profileviewer.target.text = pss.getTargetList(resourceHelper, dateUtil)
binding.profileviewer.basalGraph.show(pss)
if (pss.isValid("NSProfileFragment", activePlugin.activePump, config, resourceHelper, rxBus)) {
binding.profileviewer.invalidprofile.visibility = View.GONE
binding.profileswitch.visibility = View.VISIBLE
} else {

View file

@ -19,6 +19,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.profile.ns.events.EventNSProfileUpdateGUI
import info.nightscout.androidaps.receivers.DataWorker
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONObject
@ -32,6 +33,7 @@ class NSProfilePlugin @Inject constructor(
private val rxBus: RxBusWrapper,
resourceHelper: ResourceHelper,
private val sp: SP,
private val dateUtil: DateUtil,
config: Config
) : PluginBase(PluginDescription()
.mainType(PluginType.PROFILE)
@ -66,7 +68,7 @@ class NSProfilePlugin @Inject constructor(
val profileString = sp.getStringOrNull("profile", null)
if (profileString != null) {
aapsLogger.debug(LTag.PROFILE, "Loaded profile: $profileString")
profile = ProfileStore(injector, JSONObject(profileString))
profile = ProfileStore(injector, JSONObject(profileString), dateUtil)
} else {
aapsLogger.debug(LTag.PROFILE, "Stored profile not found")
// force restart of nsclient to fetch profile
@ -85,6 +87,7 @@ class NSProfilePlugin @Inject constructor(
@Inject lateinit var nsProfilePlugin: NSProfilePlugin
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var dataWorker: DataWorker
init {
@ -94,7 +97,7 @@ class NSProfilePlugin @Inject constructor(
override fun doWork(): Result {
val profileString = dataWorker.pickupJSONObject(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))
nsProfilePlugin.profile = ProfileStore(injector, profileString)
nsProfilePlugin.profile = ProfileStore(injector, profileString, dateUtil)
nsProfilePlugin.storeNSProfile()
if (nsProfilePlugin.isEnabled()) {
rxBus.send(EventProfileStoreChanged())

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.pump.mdi
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger

View file

@ -7,7 +7,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.interfaces.*
@ -95,7 +95,7 @@ open class VirtualPumpPlugin @Inject constructor(
it.is30minBasalRatesCapable = true
}
fun getFakingStatus(): Boolean {
private fun getFakingStatus(): Boolean {
return sp.getBoolean(R.string.key_fromNSAreCommingFakedExtendedBoluses, false)
}
@ -169,7 +169,7 @@ open class VirtualPumpPlugin @Inject constructor(
}
override val baseBasalRate: Double
get() = profileFunction.getProfile()?.basal ?: 0.0
get() = profileFunction.getProfile()?.getBasal() ?: 0.0
override val reservoirLevel: Double
get() = reservoirInUnits.toDouble()

View file

@ -3,14 +3,13 @@ package info.nightscout.androidaps.plugins.sensitivity
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
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.db.ProfileSwitch
import info.nightscout.androidaps.extensions.isEvent5minBack
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.extensions.isEPSEvent5minBack
import info.nightscout.androidaps.extensions.isTherapyEventEvent5minBack
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.Sensitivity.SensitivityType
import info.nightscout.androidaps.logging.AAPSLogger
@ -36,7 +35,6 @@ open class SensitivityAAPSPlugin @Inject constructor(
sp: SP,
private val profileFunction: ProfileFunction,
private val dateUtil: DateUtil,
private val databaseHelper: DatabaseHelperInterface,
private val repository: AppRepository
) : AbstractSensitivityPlugin(PluginDescription()
.mainType(PluginType.SENSITIVITY)
@ -70,7 +68,7 @@ open class SensitivityAAPSPlugin @Inject constructor(
return AutosensResult()
}
val siteChanges = repository.getTherapyEventDataFromTime(fromTime, TherapyEvent.Type.CANNULA_CHANGE, true).blockingGet()
val profileSwitches = databaseHelper.getProfileSwitchEventsFromTime(fromTime, true)
val profileSwitches = repository.getEffectiveProfileSwitchDataFromTime(fromTime, true).blockingGet()
val deviationsArray: MutableList<Double> = ArrayList()
var pastSensitivity = ""
var index = 0
@ -86,13 +84,13 @@ open class SensitivityAAPSPlugin @Inject constructor(
}
// reset deviations after site change
if (isEvent5minBack(siteChanges, autosensData.time)) {
if (siteChanges.isTherapyEventEvent5minBack(autosensData.time)) {
deviationsArray.clear()
pastSensitivity += "(SITECHANGE)"
}
// reset deviations after profile switch
if (ProfileSwitch(injector).isEvent5minBack(profileSwitches, autosensData.time, true)) {
if (profileSwitches.isEPSEvent5minBack(autosensData.time)) {
deviationsArray.clear()
pastSensitivity += "(PROFILESWITCH)"
}
@ -110,14 +108,14 @@ open class SensitivityAAPSPlugin @Inject constructor(
index++
}
val deviations = Array(deviationsArray.size) { i -> deviationsArray[i] }
val sens = profile.isfMgdl
val sens = profile.getIsfMgdl()
val ratioLimit = ""
val sensResult: String
aapsLogger.debug(LTag.AUTOSENS, "Records: $index $pastSensitivity")
Arrays.sort(deviations)
val percentile = IobCobCalculatorPlugin.percentile(deviations, 0.50)
val basalOff = percentile * (60.0 / 5.0) / sens
val ratio = 1 + basalOff / profile.maxDailyBasal
val ratio = 1 + basalOff / profile.getMaxDailyBasal()
sensResult = when {
percentile < 0 -> "Excess insulin sensitivity detected"
percentile > 0 -> "Excess insulin resistance detected"

View file

@ -3,14 +3,13 @@ package info.nightscout.androidaps.plugins.sensitivity
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
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.db.ProfileSwitch
import info.nightscout.androidaps.extensions.isEvent5minBack
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.extensions.isEPSEvent5minBack
import info.nightscout.androidaps.extensions.isTherapyEventEvent5minBack
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.Sensitivity.SensitivityType
import info.nightscout.androidaps.logging.AAPSLogger
@ -37,7 +36,6 @@ open class SensitivityOref1Plugin @Inject constructor(
sp: SP,
private val profileFunction: ProfileFunction,
private val dateUtil: DateUtil,
private val databaseHelper: DatabaseHelperInterface,
private val repository: AppRepository
) : AbstractSensitivityPlugin(PluginDescription()
.mainType(PluginType.SENSITIVITY)
@ -71,7 +69,7 @@ open class SensitivityOref1Plugin @Inject constructor(
return AutosensResult()
}
val siteChanges = repository.getTherapyEventDataFromTime(fromTime, TherapyEvent.Type.CANNULA_CHANGE, true).blockingGet()
val profileSwitches = databaseHelper.getProfileSwitchEventsFromTime(fromTime, true)
val profileSwitches = repository.getEffectiveProfileSwitchDataFromTime(fromTime, true).blockingGet()
//[0] = 8 hour
//[1] = 24 hour
@ -102,14 +100,14 @@ open class SensitivityOref1Plugin @Inject constructor(
var pastSensitivity = pastSensitivityArray[hourSegment]
// reset deviations after site change
if (isEvent5minBack(siteChanges, autosensData.time)) {
if (siteChanges.isTherapyEventEvent5minBack(autosensData.time)) {
deviationsArray.clear()
pastSensitivity += "(SITECHANGE)"
pastSensitivity += "(SITECHANGE)"
}
// reset deviations after profile switch
if (ProfileSwitch(injector).isEvent5minBack(profileSwitches, autosensData.time, true)) {
if (profileSwitches.isEPSEvent5minBack(autosensData.time)) {
deviationsArray.clear()
pastSensitivity += "(PROFILESWITCH)"
}
@ -159,7 +157,7 @@ open class SensitivityOref1Plugin @Inject constructor(
if (hourUsed == 1) sensResult = "(24 hours) "
val ratioLimit = ""
val deviations: Array<Double> = Array(deviationsArray.size) { i -> deviationsArray[i] }
val sens = profile.isfMgdl
val sens = profile.getIsfMgdl()
aapsLogger.debug(LTag.AUTOSENS, "Records: $index $pastSensitivity")
Arrays.sort(deviations)
val pSensitive = IobCobCalculatorPlugin.percentile(deviations, 0.50)
@ -179,7 +177,7 @@ open class SensitivityOref1Plugin @Inject constructor(
else -> sensResult += "Sensitivity normal"
}
aapsLogger.debug(LTag.AUTOSENS, sensResult)
val ratio = 1 + basalOff / profile.maxDailyBasal
val ratio = 1 + basalOff / profile.getMaxDailyBasal()
//Update the data back to the parent
sensResultArray[hourUsed] = sensResult

View file

@ -4,14 +4,13 @@ import androidx.collection.LongSparseArray
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
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.db.ProfileSwitch
import info.nightscout.androidaps.extensions.isEvent5minBack
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.extensions.isEPSEvent5minBack
import info.nightscout.androidaps.extensions.isTherapyEventEvent5minBack
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.Sensitivity.SensitivityType
import info.nightscout.androidaps.logging.AAPSLogger
@ -35,7 +34,6 @@ open class SensitivityWeightedAveragePlugin @Inject constructor(
sp: SP,
private val profileFunction: ProfileFunction,
private val dateUtil: DateUtil,
private val databaseHelper: DatabaseHelperInterface,
private val repository: AppRepository
) : AbstractSensitivityPlugin(PluginDescription()
.mainType(PluginType.SENSITIVITY)
@ -69,7 +67,7 @@ open class SensitivityWeightedAveragePlugin @Inject constructor(
return AutosensResult()
}
val siteChanges = repository.getTherapyEventDataFromTime(fromTime, TherapyEvent.Type.CANNULA_CHANGE, true).blockingGet()
val profileSwitches = databaseHelper.getProfileSwitchEventsFromTime(fromTime, true)
val profileSwitches = repository.getEffectiveProfileSwitchDataFromTime(fromTime, true).blockingGet()
var pastSensitivity = ""
var index = 0
val data = LongSparseArray<Double>()
@ -89,13 +87,13 @@ open class SensitivityWeightedAveragePlugin @Inject constructor(
}
// reset deviations after site change
if (isEvent5minBack(siteChanges, autosensData.time)) {
if (siteChanges.isTherapyEventEvent5minBack(autosensData.time)) {
data.clear()
pastSensitivity += "(SITECHANGE)"
}
// reset deviations after profile switch
if (ProfileSwitch(injector).isEvent5minBack(profileSwitches, autosensData.time, true)) {
if (profileSwitches.isEPSEvent5minBack(autosensData.time)) {
data.clear()
pastSensitivity += "(PROFILESWITCH)"
}
@ -133,13 +131,13 @@ open class SensitivityWeightedAveragePlugin @Inject constructor(
if (weights == 0.0) {
return AutosensResult()
}
val sens = profile.isfMgdl
val sens = profile.getIsfMgdl()
val ratioLimit = ""
val sensResult: String
aapsLogger.debug(LTag.AUTOSENS, "Records: $index $pastSensitivity")
val average = weightedSum / weights
val basalOff = average * (60 / 5.0) / sens
val ratio = 1 + basalOff / profile.maxDailyBasal
val ratio = 1 + basalOff / profile.getMaxDailyBasal()
sensResult = when {
average < 0 -> "Excess insulin sensitivity detected"
average > 0 -> "Excess insulin resistance detected"

View file

@ -10,15 +10,19 @@ 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.ValueWithUnit
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.transactions.InvalidateGlucoseValueTransaction
import info.nightscout.androidaps.databinding.BgsourceFragmentBinding
import info.nightscout.androidaps.databinding.BgsourceItemBinding
import info.nightscout.androidaps.events.EventNewBG
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.extensions.directionToIcon
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.extensions.valueToUnitsString
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -26,11 +30,6 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.extensions.directionToIcon
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.extensions.valueToUnitsString
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import io.reactivex.disposables.CompositeDisposable
@ -45,7 +44,6 @@ class BGSourceFragment : DaggerFragment() {
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var repository: AppRepository
@Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var uel: UserEntryLogger

View file

@ -2,9 +2,6 @@ package info.nightscout.androidaps.plugins.treatments;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.List;
import java.util.stream.Collectors;
@ -15,29 +12,21 @@ import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.ProfileIntervals;
import info.nightscout.androidaps.database.AppRepository;
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.db.Treatment;
import info.nightscout.androidaps.events.EventReloadProfileSwitchData;
import info.nightscout.androidaps.interfaces.ActivePlugin;
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
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.interfaces.ProfileStore;
import info.nightscout.androidaps.interfaces.TreatmentServiceInterface;
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
@ -48,11 +37,9 @@ import io.reactivex.disposables.CompositeDisposable;
@Singleton
public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface {
private final Context context;
private final AapsSchedulers aapsSchedulers;
private final SP sp;
private final RxBusWrapper rxBus;
private final ResourceHelper resourceHelper;
private final ProfileFunction profileFunction;
private final ActivePlugin activePlugin;
private final NSUpload nsUpload;
@ -65,8 +52,6 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
protected TreatmentServiceInterface service;
private final ProfileIntervals<ProfileSwitch> profiles = new ProfileIntervals<>();
@Inject
public TreatmentsPlugin(
HasAndroidInjector injector,
@ -95,8 +80,6 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
.setDefault(),
aapsLogger, resourceHelper, injector
);
this.resourceHelper = resourceHelper;
this.context = context;
this.rxBus = rxBus;
this.aapsSchedulers = aapsSchedulers;
this.sp = sp;
@ -112,14 +95,13 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
@Override
protected void onStart() {
this.service = new TreatmentService(getInjector());
initializeData(range());
super.onStart();
disposable.add(rxBus
.toObservable(EventReloadProfileSwitchData.class)
.observeOn(aapsSchedulers.getIo())
.subscribe(event -> initializeProfileSwitchData(range()),
fabricPrivacy::logException
));
// disposable.add(rxBus
// .toObservable(EventReloadProfileSwitchData.class)
// .observeOn(aapsSchedulers.getIo())
// .subscribe(event -> initializeProfileSwitchData(range()),
// fabricPrivacy::logException
// ));
}
@Override
@ -140,17 +122,6 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
return (long) (60 * 60 * 1000L * (24 + dia));
}
public void initializeData(long range) {
initializeProfileSwitchData(range);
}
private void initializeProfileSwitchData(long range) {
getAapsLogger().debug(LTag.DATATREATMENTS, "initializeProfileSwitchData");
synchronized (profiles) {
profiles.reset().add(databaseHelper.getProfileSwitchData(dateUtil.now() - range, false));
}
}
/**
* Returns all Treatments after specified timestamp. Also returns invalid entries (required to
* map "Fill Cannula" entries to history (and not to add double bolus for it)
@ -339,56 +310,4 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
return newRecordCreated;
*/
}
@Override
@Nullable
public ProfileSwitch getProfileSwitchFromHistory(long time) {
synchronized (profiles) {
return (ProfileSwitch) profiles.getValueToTime(time);
}
}
@Override
public ProfileIntervals<ProfileSwitch> getProfileSwitchesFromHistory() {
synchronized (profiles) {
return new ProfileIntervals<>(profiles);
}
}
@Override
public void addToHistoryProfileSwitch(ProfileSwitch profileSwitch) {
//log.debug("Adding new TemporaryBasal record" + profileSwitch.log());
rxBus.send(new EventDismissNotification(Notification.PROFILE_SWITCH_MISSING));
databaseHelper.createOrUpdate(profileSwitch);
nsUpload.uploadProfileSwitch(profileSwitch, profileSwitch.date, dateUtil);
}
@Override
public void doProfileSwitch(@NonNull final ProfileStore profileStore, @NonNull final String profileName, final int duration, final int percentage, final int timeShift, final long date) {
ProfileSwitch profileSwitch = profileFunction.prepareProfileSwitch(profileStore, profileName, duration, percentage, timeShift, date);
addToHistoryProfileSwitch(profileSwitch);
if (percentage == 90 && duration == 10)
sp.putBoolean(R.string.key_objectiveuseprofileswitch, true);
}
@Override
public void doProfileSwitch(final int duration, final int percentage, final int timeShift) {
ProfileSwitch profileSwitch = getProfileSwitchFromHistory(System.currentTimeMillis());
if (profileSwitch != null) {
profileSwitch = new ProfileSwitch(getInjector());
profileSwitch.date = System.currentTimeMillis();
profileSwitch.source = Source.USER;
profileSwitch.profileName = profileFunction.getProfileName(System.currentTimeMillis(), false, false);
profileSwitch.profileJson = profileFunction.getProfile().getData().toString();
profileSwitch.profilePlugin = activePlugin.getActiveProfileSource().getClass().getName();
profileSwitch.durationInMinutes = duration;
profileSwitch.isCPP = percentage != 100 || timeShift != 0;
profileSwitch.timeshift = timeShift;
profileSwitch.percentage = percentage;
addToHistoryProfileSwitch(profileSwitch);
} else {
getAapsLogger().error(LTag.PROFILE, "No profile switch exists");
}
}
}

View file

@ -105,7 +105,8 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
onError = { aapsLogger.error("Error removing entries", it) },
onComplete = {
rxBus.send(EventTreatmentChange())
rxBus.send(EventNewHistoryData(0, false)) }
rxBus.send(EventNewHistoryData(0, false))
}
)
rxBus.send(EventNSClientRestart())
}
@ -258,10 +259,8 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
inner class RecyclerViewAdapter internal constructor(var mealLinks: List<MealLink>) : RecyclerView.Adapter<RecyclerViewAdapter.MealLinkLoadedViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): MealLinkLoadedViewHolder {
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_bolus_carbs_item, viewGroup, false)
return MealLinkLoadedViewHolder(v)
}
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): MealLinkLoadedViewHolder =
MealLinkLoadedViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_bolus_carbs_item, viewGroup, false))
override fun onBindViewHolder(holder: MealLinkLoadedViewHolder, position: Int) {
val profile = profileFunction.getProfile() ?: return
@ -283,7 +282,8 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
holder.binding.bolusInvalid.visibility = bolus.isValid.not().toVisibility()
val iob = bolus.iobCalc(activePlugin, System.currentTimeMillis(), profile.dia)
holder.binding.iob.text = resourceHelper.gs(R.string.formatinsulinunits, iob.iobContrib)
if (iob.iobContrib != 0.0) holder.binding.iob.setTextColor(resourceHelper.gc(R.color.colorActive)) else holder.binding.iob.setTextColor(holder.binding.carbs.currentTextColor)
holder.binding.iobLabel.visibility = (iob.iobContrib != 0.0).toVisibility()
holder.binding.iob.visibility = (iob.iobContrib != 0.0).toVisibility()
if (bolus.timestamp > dateUtil.now()) holder.binding.date.setTextColor(resourceHelper.gc(R.color.colorScheduled)) else holder.binding.date.setTextColor(holder.binding.carbs.currentTextColor)
holder.binding.mealOrCorrection.text =
when (ml.bolus.type) {

View file

@ -9,42 +9,49 @@ 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.entities.ValueWithUnit
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.transactions.InvalidateProfileSwitchTransaction
import info.nightscout.androidaps.databinding.TreatmentsProfileswitchFragmentBinding
import info.nightscout.androidaps.databinding.TreatmentsProfileswitchItemBinding
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
import info.nightscout.androidaps.events.EventProfileNeedsUpdate
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.events.EventProfileSwitchChanged
import info.nightscout.androidaps.extensions.getCustomizedName
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.interfaces.UploadQueueInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
import info.nightscout.androidaps.plugins.treatments.events.EventTreatmentUpdateGui
import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsProfileSwitchFragment.RecyclerProfileViewAdapter.ProfileSwitchViewHolder
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.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 javax.inject.Inject
class TreatmentsProfileSwitchFragment : DaggerFragment() {
private val disposable = CompositeDisposable()
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var sp: SP
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var localProfilePlugin: LocalProfilePlugin
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@ -53,11 +60,15 @@ class TreatmentsProfileSwitchFragment : 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 var _binding: TreatmentsProfileswitchFragmentBinding? = null
private val disposable = CompositeDisposable()
private val millsToThePast = T.days(30).msecs()
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
@ -69,29 +80,82 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
super.onViewCreated(view, savedInstanceState)
binding.recyclerview.setHasFixedSize(true)
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
binding.recyclerview.adapter = RecyclerProfileViewAdapter(databaseHelper.getProfileSwitchData(dateUtil.now() - T.days(30).msecs(), false))
binding.refreshFromNightscout.setOnClickListener {
activity?.let { activity ->
uel.log(Action.PROFILE_SWITCH_NS_REFRESH, Sources.Treatments)
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.refresheventsfromnightscout) + "?") {
databaseHelper.resetProfileSwitch()
uel.log(Action.TREATMENTS_NS_REFRESH, Sources.Treatments)
disposable +=
Completable.fromAction {
repository.deleteAllEffectiveProfileSwitches()
repository.deleteAllProfileSwitches()
}
.subscribeOn(aapsSchedulers.io)
.observeOn(aapsSchedulers.main)
.subscribeBy(
onError = { aapsLogger.error("Error removing entries", it) },
onComplete = {
rxBus.send(EventProfileSwitchChanged())
rxBus.send(EventNewHistoryData(0, false))
}
)
rxBus.send(EventNSClientRestart())
}
}
}
if (sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode()) binding.refreshFromNightscout.visibility = View.GONE
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
rxBus.send(EventTreatmentUpdateGui())
}
}
private fun profileSwitchWithInvalid(now: Long) = repository
.getProfileSwitchDataIncludingInvalidFromTime(now - millsToThePast, false)
.map { bolus -> bolus.map { ProfileSealed.PS(it) } }
private fun effectiveProfileSwitchWithInvalid(now: Long) = repository
.getEffectiveProfileSwitchDataIncludingInvalidFromTime(now - millsToThePast, false)
.map { carb -> carb.map { ProfileSealed.EPS(it) } }
private fun profileSwitches(now: Long) = repository
.getProfileSwitchDataFromTime(now - millsToThePast, false)
.map { bolus -> bolus.map { ProfileSealed.PS(it) } }
private fun effectiveProfileSwitches(now: Long) = repository
.getEffectiveProfileSwitchDataFromTime(now - millsToThePast, false)
.map { carb -> carb.map { ProfileSealed.EPS(it) } }
fun swapAdapter() {
val now = System.currentTimeMillis()
if (binding.showInvalidated.isChecked)
disposable += profileSwitchWithInvalid(now)
.zipWith(effectiveProfileSwitchWithInvalid(now)) { first, second -> first + second }
.map { ml -> ml.sortedByDescending { it.timestamp } }
.observeOn(aapsSchedulers.main)
.subscribe { list ->
binding.recyclerview.swapAdapter(RecyclerProfileViewAdapter(list), true)
}
else
disposable += profileSwitches(now)
.zipWith(effectiveProfileSwitches(now)) { first, second -> first + second }
.map { ml -> ml.sortedByDescending { it.timestamp } }
.observeOn(aapsSchedulers.main)
.subscribe { list ->
binding.recyclerview.swapAdapter(RecyclerProfileViewAdapter(list), true)
}
}
@Synchronized
override fun onResume() {
super.onResume()
swapAdapter()
disposable.add(rxBus
.toObservable(EventProfileNeedsUpdate::class.java)
.toObservable(EventProfileSwitchChanged::class.java)
.observeOn(aapsSchedulers.main)
.subscribe({ updateGUI() }, fabricPrivacy::logException)
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
)
updateGUI()
}
@Synchronized
@ -103,36 +167,34 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
@Synchronized
override fun onDestroyView() {
super.onDestroyView()
binding.recyclerview.adapter = null // avoid leaks
_binding = null
}
fun updateGUI() {
if (_binding == null) return
binding.recyclerview.swapAdapter(RecyclerProfileViewAdapter(databaseHelper.getProfileSwitchData(dateUtil.now() - T.days(30).msecs(), false)), false)
}
inner class RecyclerProfileViewAdapter(private var profileSwitchList: List<ProfileSwitch>) : RecyclerView.Adapter<ProfileSwitchViewHolder>() {
inner class RecyclerProfileViewAdapter(private var profileSwitchList: List<ProfileSealed>) : RecyclerView.Adapter<ProfileSwitchViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ProfileSwitchViewHolder =
ProfileSwitchViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_profileswitch_item, viewGroup, false))
override fun onBindViewHolder(holder: ProfileSwitchViewHolder, position: Int) {
val profileSwitch = profileSwitchList[position]
holder.binding.ph.visibility = (profileSwitch.source == Source.PUMP).toVisibility()
holder.binding.ns.visibility = NSUpload.isIdValid(profileSwitch._id).toVisibility()
holder.binding.date.text = dateUtil.dateAndTimeString(profileSwitch.date)
if (!profileSwitch.isEndingEvent) {
holder.binding.duration.text = resourceHelper.gs(R.string.format_mins, profileSwitch.durationInMinutes)
} else {
holder.binding.duration.text = ""
}
holder.binding.name.text = profileSwitch.customizedName
if (profileSwitch.isInProgress) holder.binding.date.setTextColor(resourceHelper.gc(R.color.colorActive)) else holder.binding.date.setTextColor(holder.binding.duration.currentTextColor)
holder.binding.ph.visibility = (profileSwitch is ProfileSealed.EPS).toVisibility()
holder.binding.ns.visibility = (profileSwitch.interfaceIDs_backing?.nightscoutId != null).toVisibility()
holder.binding.date.text = dateUtil.dateAndTimeString(profileSwitch.timestamp)
holder.binding.duration.text = resourceHelper.gs(R.string.format_mins, T.msecs(profileSwitch.duration ?: 0L).mins())
holder.binding.name.text = if (profileSwitch is ProfileSealed.PS) profileSwitch.value.getCustomizedName() else if (profileSwitch is ProfileSealed.EPS) profileSwitch.value.originalCustomizedName else ""
if (profileSwitch.isInProgress(dateUtil)) holder.binding.date.setTextColor(resourceHelper.gc(R.color.colorActive))
else holder.binding.date.setTextColor(holder.binding.duration.currentTextColor)
holder.binding.remove.tag = profileSwitch
holder.binding.clone.tag = profileSwitch
holder.binding.name.tag = profileSwitch
holder.binding.date.tag = profileSwitch
holder.binding.invalid.visibility = if (profileSwitch.isValid) View.GONE else View.VISIBLE
holder.binding.invalid.visibility = profileSwitch.isValid.not().toVisibility()
holder.binding.duration.visibility = (profileSwitch.duration != 0L && profileSwitch.duration != null).toVisibility()
holder.binding.remove.visibility = (profileSwitch is ProfileSealed.PS).toVisibility()
holder.binding.clone.visibility = (profileSwitch is ProfileSealed.PS).toVisibility()
holder.binding.spacer.visibility = (profileSwitch is ProfileSealed.PS).toVisibility()
holder.binding.root.setBackgroundColor(resourceHelper.gc(if (profileSwitch is ProfileSealed.PS) R.color.defaultbackground else R.color.list_delimiter))
}
override fun getItemCount(): Int {
@ -144,38 +206,34 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
val binding = TreatmentsProfileswitchItemBinding.bind(itemView)
init {
binding.remove.setOnClickListener {
val profileSwitch = it.tag as ProfileSwitch
binding.remove.setOnClickListener { view ->
val profileSwitch = view.tag as ProfileSealed.PS
activity?.let { activity ->
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.removerecord),
resourceHelper.gs(R.string.careportal_profileswitch) + ": " + profileSwitch.profileName +
"\n" + resourceHelper.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(profileSwitch.date), Runnable {
"\n" + resourceHelper.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(profileSwitch.timestamp), Runnable {
uel.log(Action.PROFILE_SWITCH_REMOVED, Sources.Treatments, profileSwitch.profileName,
ValueWithUnit.Timestamp(profileSwitch.date))
val id = profileSwitch._id
if (NSUpload.isIdValid(id)) nsUpload.removeCareportalEntryFromNS(id)
else uploadQueue.removeByMongoId("dbAdd", id)
databaseHelper.delete(profileSwitch)
ValueWithUnit.Timestamp(profileSwitch.timestamp))
disposable += repository.runTransactionForResult(InvalidateProfileSwitchTransaction(profileSwitch.id))
.subscribe(
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it") } },
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating ProfileSwitch", it) }
)
})
}
}
binding.clone.setOnClickListener {
activity?.let { activity ->
val profileSwitch = it.tag as ProfileSwitch
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal_profileswitch), resourceHelper.gs(R.string.copytolocalprofile) + "\n" + profileSwitch.customizedName + "\n" + dateUtil.dateAndTimeString(profileSwitch.date), Runnable {
profileSwitch.profileObject?.let {
val profileSwitch = (it.tag as ProfileSealed.PS).value
val profileSealed = it.tag as ProfileSealed
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal_profileswitch), resourceHelper.gs(R.string.copytolocalprofile) + "\n" + profileSwitch.getCustomizedName() + "\n" + dateUtil.dateAndTimeString(profileSwitch.timestamp), Runnable {
uel.log(Action.PROFILE_SWITCH_CLONED, Sources.Treatments,
profileSwitch.customizedName + " " + dateUtil.dateAndTimeString(profileSwitch.date).replace(".", "_"),
ValueWithUnit.Timestamp(profileSwitch.date),
profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_"),
ValueWithUnit.Timestamp(profileSwitch.timestamp),
ValueWithUnit.SimpleString(profileSwitch.profileName))
val nonCustomized = it.convertToNonCustomizedProfile()
if (nonCustomized.isValid(resourceHelper.gs(R.string.careportal_profileswitch, false))) {
localProfilePlugin.addProfile(localProfilePlugin.copyFrom(nonCustomized, profileSwitch.customizedName + " " + dateUtil.dateAndTimeString(profileSwitch.date).replace(".", "_")))
val nonCustomized = profileSealed.convertToNonCustomizedProfile(dateUtil)
localProfilePlugin.addProfile(localProfilePlugin.copyFrom(nonCustomized, profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_")))
rxBus.send(EventLocalProfileChanged())
} else {
OKDialog.show(activity, resourceHelper.gs(R.string.careportal_profileswitch), resourceHelper.gs(R.string.copytolocalprofile_invalid))
}
}
})
}
}
@ -184,7 +242,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
binding.name.setOnClickListener {
ProfileViewerDialog().also { pvd ->
pvd.arguments = Bundle().also { args ->
args.putLong("time", (it.tag as ProfileSwitch).date)
args.putLong("time", (it.tag as ProfileSealed).timestamp)
args.putInt("mode", ProfileViewerDialog.Mode.DB_PROFILE.ordinal)
}
pvd.show(childFragmentManager, "ProfileViewDialog")
@ -193,7 +251,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
binding.date.setOnClickListener {
ProfileViewerDialog().also { pvd ->
pvd.arguments = Bundle().also { args ->
args.putLong("time", (it.tag as ProfileSwitch).date)
args.putLong("time", (it.tag as ProfileSealed).timestamp)
args.putInt("mode", ProfileViewerDialog.Mode.DB_PROFILE.ordinal)
}
pvd.show(childFragmentManager, "ProfileViewDialog")

View file

@ -5,24 +5,24 @@ import android.content.Intent
import android.os.SystemClock
import android.text.Spanned
import androidx.appcompat.app.AppCompatActivity
import dagger.Lazy
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.BolusProgressHelperActivity
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
import info.nightscout.androidaps.database.entities.ProfileSwitch
import info.nightscout.androidaps.database.interfaces.end
import info.nightscout.androidaps.dialogs.BolusProgressDialog
import info.nightscout.androidaps.events.EventBolusRequested
import info.nightscout.androidaps.events.EventNewBasalProfile
import info.nightscout.androidaps.events.EventProfileNeedsUpdate
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.events.EventProfileSwitchChanged
import info.nightscout.androidaps.extensions.getCustomizedName
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -56,7 +56,7 @@ open class CommandQueue @Inject constructor(
private val resourceHelper: ResourceHelper,
private val constraintChecker: ConstraintChecker,
private val profileFunction: ProfileFunction,
private val activePlugin: Lazy<ActivePlugin>,
private val activePlugin: ActivePlugin,
private val context: Context,
private val sp: SP,
private val buildHelper: BuildHelper,
@ -74,17 +74,37 @@ open class CommandQueue @Inject constructor(
init {
disposable.add(rxBus
.toObservable(EventProfileNeedsUpdate::class.java)
.toObservable(EventProfileSwitchChanged::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({
aapsLogger.debug(LTag.PROFILE, "onProfileSwitch")
profileFunction.getProfile()?.let {
setProfile(it, object : Callback() {
profileFunction.getRequestedProfile()?.let {
val nonCustomized = ProfileSealed.PS(it).convertToNonCustomizedProfile(dateUtil)
setProfile(ProfileSealed.Pure(nonCustomized), it.interfaceIDs.nightscoutId != null, object : Callback() {
override fun run() {
if (!result.success) {
ErrorHelperActivity.runAlarm(context, result.comment, resourceHelper.gs(R.string.failedupdatebasalprofile), R.raw.boluserror)
}
if (result.enacted) rxBus.send(EventNewBasalProfile())
if (result.enacted) {
rxBus.send(EventNewBasalProfile())
repository.createEffectiveProfileSwitch(
EffectiveProfileSwitch(
timestamp = dateUtil.now(),
basalBlocks = nonCustomized.basalBlocks,
isfBlocks = nonCustomized.isfBlocks,
icBlocks = nonCustomized.icBlocks,
targetBlocks = nonCustomized.targetBlocks,
glucoseUnit = if (it.glucoseUnit == ProfileSwitch.GlucoseUnit.MGDL) EffectiveProfileSwitch.GlucoseUnit.MGDL else EffectiveProfileSwitch.GlucoseUnit.MMOL,
originalProfileName = it.profileName,
originalCustomizedName = it.getCustomizedName(),
originalTimeshift = it.timeshift,
originalPercentage = it.percentage,
originalDuration = it.duration,
originalEnd = it.end,
insulinConfiguration = it.insulinConfiguration
)
)
}
}
})
}
@ -156,7 +176,7 @@ open class CommandQueue @Inject constructor(
open fun notifyAboutNewCommand() {
waitForFinishedThread()
if (thread == null || thread!!.state == Thread.State.TERMINATED) {
thread = QueueThread(this, context, aapsLogger, rxBus, activePlugin.get(), resourceHelper, sp)
thread = QueueThread(this, context, aapsLogger, rxBus, activePlugin, resourceHelper, sp)
thread!!.start()
aapsLogger.debug(LTag.PUMPQUEUE, "Starting new thread")
} else {
@ -199,7 +219,7 @@ open class CommandQueue @Inject constructor(
// If not, it's not necessary add command to the queue and initiate connection
// Assuming carbs in the future and carbs with duration are NOT stores anyway
if ((detailedBolusInfo.carbs > 0) &&
(!activePlugin.get().activePump.pumpDescription.storesCarbInfo ||
(!activePlugin.activePump.pumpDescription.storesCarbInfo ||
detailedBolusInfo.carbsDuration != 0L ||
(detailedBolusInfo.carbsTimestamp ?: detailedBolusInfo.timestamp) > dateUtil.now())
) {
@ -286,7 +306,7 @@ open class CommandQueue @Inject constructor(
}
removeAll(CommandType.BOLUS)
removeAll(CommandType.SMB_BOLUS)
Thread { activePlugin.get().activePump.stopBolusDelivering() }.run()
Thread { activePlugin.activePump.stopBolusDelivering() }.run()
}
// returns true if command is queued
@ -363,8 +383,8 @@ open class CommandQueue @Inject constructor(
}
// returns true if command is queued
override fun setProfile(profile: Profile, callback: Callback?): Boolean {
if (isThisProfileSet(profile)) {
override fun setProfile(profile: Profile, hasNsId: Boolean, callback: Callback?): Boolean {
if (isThisProfileSet(profile) && repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing) {
aapsLogger.debug(LTag.PUMPQUEUE, "Correct profile already set")
callback?.result(PumpEnactResult(injector).success(true).enacted(false))?.run()
return false
@ -378,9 +398,9 @@ open class CommandQueue @Inject constructor(
}
*/
// Compare with pump limits
val basalValues = profile.basalValues
val basalValues = profile.getBasalValues()
for (basalValue in basalValues) {
if (basalValue.value < activePlugin.get().activePump.pumpDescription.basalMinimumRate) {
if (basalValue.value < activePlugin.activePump.pumpDescription.basalMinimumRate) {
val notification = Notification(Notification.BASAL_VALUE_BELOW_MINIMUM, resourceHelper.gs(R.string.basalvaluebelowminimum), Notification.URGENT)
rxBus.send(EventNewNotification(notification))
callback?.result(PumpEnactResult(injector).success(false).enacted(false).comment(R.string.basalvaluebelowminimum))?.run()
@ -391,7 +411,7 @@ open class CommandQueue @Inject constructor(
// remove all unfinished
removeAll(CommandType.BASAL_PROFILE)
// add new command to queue
add(CommandSetProfile(injector, profile, callback))
add(CommandSetProfile(injector, profile, hasNsId, callback))
notifyAboutNewCommand()
return true
}
@ -547,16 +567,12 @@ open class CommandQueue @Inject constructor(
}
override fun isThisProfileSet(profile: Profile): Boolean {
val activePump = activePlugin.get().activePump
val current = profileFunction.getProfile()
return if (current != null) {
val result = activePump.isThisProfileSet(profile)
val result = activePlugin.activePump.isThisProfileSet(profile)
if (!result) {
aapsLogger.debug(LTag.PUMPQUEUE, "Current profile: $current")
aapsLogger.debug(LTag.PUMPQUEUE, "Current profile: ${profileFunction.getProfile()}")
aapsLogger.debug(LTag.PUMPQUEUE, "New profile: $profile")
}
result
} else true
return result
}
private fun showBolusProgressDialog(insulin: Double, ctx: Context?) {

View file

@ -2,25 +2,28 @@ package info.nightscout.androidaps.queue.commands
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.DateUtil
import javax.inject.Inject
class CommandSetProfile constructor(
injector: HasAndroidInjector,
private val profile: Profile,
private val hasNsId: Boolean,
callback: Callback?
) : Command(injector, CommandType.BASAL_PROFILE, callback) {
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var commandQueue: CommandQueueProvider
override fun execute() {
@ -33,13 +36,12 @@ class CommandSetProfile constructor(
aapsLogger.debug(LTag.PUMPQUEUE, "Result success: ${r.success} enacted: ${r.enacted} profile: $profile")
callback?.result(r)?.run()
// Send SMS notification if ProfileSwitch is coming from NS
val profileSwitch = activePlugin.activeTreatments.getProfileSwitchFromHistory(System.currentTimeMillis())
if (profileSwitch != null && r.enacted && profileSwitch.source == Source.NIGHTSCOUT) {
if (smsCommunicatorPlugin.isEnabled(PluginType.GENERAL)) {
val profileSwitch = repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet()
if (profileSwitch is ValueWrapper.Existing && r.enacted && hasNsId) {
if (smsCommunicatorPlugin.isEnabled(PluginType.GENERAL))
smsCommunicatorPlugin.sendNotificationToAllNumbers(resourceHelper.gs(R.string.profile_set_ok))
}
}
}
override fun status(): String = "SET PROFILE"
}

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.queue.commands
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.LTag

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.queue.commands
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.LTag

View file

@ -14,9 +14,10 @@ import androidx.work.WorkerParameters
import dagger.android.DaggerBroadcastReceiver
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.events.EventProfileNeedsUpdate
import info.nightscout.androidaps.events.EventProfileSwitchChanged
import info.nightscout.androidaps.extensions.buildDeviceStatus
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueueProvider
@ -117,10 +118,11 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
private fun checkPump() {
val pump = activePlugin.activePump
val profile = profileFunction.getProfile() ?: return
val ps = profileFunction.getRequestedProfile() ?: return
val profile = ProfileSealed.PS(ps)
val lastConnection = pump.lastDataTime()
val isStatusOutdated = lastConnection + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis()
val isBasalOutdated = abs(profile.basal - pump.baseBasalRate) > pump.pumpDescription.basalStep
val isBasalOutdated = abs(profile.getBasal() - pump.baseBasalRate) > pump.pumpDescription.basalStep
aapsLogger.debug(LTag.CORE, "Last connection: " + dateUtil.dateAndTimeString(lastConnection))
// sometimes keep alive broadcast stops
// as as workaround test if readStatus was requested before an alarm is generated
@ -128,7 +130,7 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
localAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated, loopPlugin.isDisconnected)
}
if (!pump.isThisProfileSet(profile) && !commandQueue.isRunning(Command.CommandType.BASAL_PROFILE)) {
rxBus.send(EventProfileNeedsUpdate())
rxBus.send(EventProfileSwitchChanged())
} else if (isStatusOutdated && !pump.isBusy()) {
lastReadStatus = System.currentTimeMillis()
commandQueue.readStatus("KeepAlive. Status outdated.", null)

View file

@ -9,6 +9,7 @@ import androidx.appcompat.app.AppCompatActivity
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.dialogs.ProfileSwitchDialog
import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.interfaces.*
@ -30,7 +31,6 @@ import info.nightscout.androidaps.setupwizard.elements.*
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.CryptoUtil
import info.nightscout.androidaps.utils.buildHelper.ConfigImpl
import info.nightscout.androidaps.utils.extensions.isRunningTest
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -57,7 +57,7 @@ class SWDefinition @Inject constructor(
private val importExportPrefs: ImportExportPrefs,
private val androidPermission: AndroidPermission,
private val cryptoUtil: CryptoUtil,
private val config: ConfigImpl
private val config: Config
) {
lateinit var activity: AppCompatActivity
@ -268,13 +268,13 @@ class SWDefinition @Inject constructor(
.label(R.string.adjustprofileinns))
.add(SWFragment(injector, this)
.add(NSProfileFragment()))
.validator { nsProfilePlugin.profile != null && nsProfilePlugin.profile!!.getDefaultProfile() != null && nsProfilePlugin.profile!!.getDefaultProfile()!!.isValid("StartupWizard") }
.validator { nsProfilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, resourceHelper, rxBus) } ?: false }
.visibility { nsProfilePlugin.isEnabled() }
private val screenLocalProfile = SWScreen(injector, R.string.localprofile)
.skippable(false)
.add(SWFragment(injector, this)
.add(LocalProfileFragment()))
.validator { localProfilePlugin.profile?.getDefaultProfile()?.isValid("StartupWizard") == true }
.validator { localProfilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, resourceHelper, rxBus) } ?: false }
.visibility { localProfilePlugin.isEnabled() }
private val screenProfileSwitch = SWScreen(injector, R.string.careportal_profileswitch)
.skippable(false)

View file

@ -9,7 +9,7 @@ import info.nightscout.androidaps.MainActivity
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.databinding.ActivitySetupwizardBinding
import info.nightscout.androidaps.events.EventProfileNeedsUpdate
import info.nightscout.androidaps.events.EventProfileSwitchChanged
import info.nightscout.androidaps.events.EventProfileStoreChanged
import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.logging.UserEntryLogger
@ -94,7 +94,7 @@ class SetupWizardActivity : NoSplashAppCompatActivity() {
.subscribe({ updateButtons() }, fabricPrivacy::logException)
)
disposable.add(rxBus
.toObservable(EventProfileNeedsUpdate::class.java)
.toObservable(EventProfileSwitchChanged::class.java)
.observeOn(aapsSchedulers.main)
.subscribe({ updateButtons() }, fabricPrivacy::logException)
)

View file

@ -7,12 +7,12 @@ import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.setupwizard.SWNumberValidator
import info.nightscout.androidaps.utils.ui.NumberPicker
import info.nightscout.androidaps.utils.SafeParse
import info.nightscout.androidaps.utils.ui.NumberPicker
import java.text.DecimalFormat
import javax.inject.Inject
@ -43,7 +43,7 @@ class SWEditNumberWithUnits(injector: HasAndroidInjector, private val init: Doub
var initValue = sp.getDouble(preferenceId, init)
initValue = Profile.toCurrentUnits(profileFunction.getUnits(), initValue)
val numberPicker = NumberPicker(context)
if (profileFunction.getUnits() == Constants.MMOL) numberPicker.setParams(initValue, min, max, 0.1, DecimalFormat("0.0"), false, null, watcher) else numberPicker.setParams(initValue, min * 18, max * 18, 1.0, DecimalFormat("0"), false, null, watcher)
if (profileFunction.getUnits() == GlucoseUnit.MMOL) numberPicker.setParams(initValue, min, max, 0.1, DecimalFormat("0.0"), false, null, watcher) else numberPicker.setParams(initValue, min * 18, max * 18, 1.0, DecimalFormat("0"), false, null, watcher)
layout.addView(numberPicker)
val c = TextView(context)

View file

@ -1,8 +1,8 @@
package info.nightscout.androidaps.utils
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.automation.actions.ActionAlarm
@ -37,21 +37,21 @@ class CarbTimer @Inject constructor(
// Bg under 180 mgdl and dropping by 15 mgdl
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
list.add(TriggerBg(injector, 180.0, Constants.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, -15.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, -8.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(TriggerBg(injector, 180.0, GlucoseUnit.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, -15.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, -8.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
})
// Bg under 160 mgdl and dropping by 9 mgdl
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
list.add(TriggerBg(injector, 160.0, Constants.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, -9.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, -5.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(TriggerBg(injector, 160.0, GlucoseUnit.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, -9.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, -5.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
})
// Bg under 145 mgdl and dropping
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
list.add(TriggerBg(injector, 145.0, Constants.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(TriggerBg(injector, 145.0, GlucoseUnit.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(TriggerDelta(injector, InputDelta(resourceHelper, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
})
}
actions.add(ActionAlarm(injector, resourceHelper.gs(R.string.time_to_eat)))

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.utils
import info.nightscout.androidaps.utils.PercentageSplitter
import java.util.regex.Pattern
object PercentageSplitter {
@ -10,7 +9,7 @@ object PercentageSplitter {
/**
* Removes the suffix for percentage and timeshift from a profile name. This is the inverse of what
* [info.nightscout.androidaps.db.ProfileSwitch.getCustomizedName] does.
* [ProfileSwitch.getCustomizedName()] does.
* Since the customized name is used for the PS upload to NS, this is needed get the original profile name
* when retrieving the PS from NS again.
*/

View file

@ -3,10 +3,10 @@ package info.nightscout.androidaps.utils
import android.content.Context
import android.content.Intent
import android.os.Bundle
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.services.Intents
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
@ -23,7 +23,7 @@ class XdripCalibrations @Inject constructor(
fun sendIntent(bg: Double): Boolean {
val bundle = Bundle()
bundle.putDouble("glucose_number", bg)
bundle.putString("units", if (profileFunction.getUnits() == Constants.MGDL) "mgdl" else "mmol")
bundle.putString("units", if (profileFunction.getUnits() == GlucoseUnit.MGDL) "mgdl" else "mmol")
bundle.putLong("timestamp", System.currentTimeMillis())
val intent = Intent(Intents.ACTION_REMOTE_CALIBRATION)
intent.putExtras(bundle)

View file

@ -4,7 +4,7 @@ import android.text.Spanned
import android.util.LongSparseArray
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.utils.DateUtil

View file

@ -9,7 +9,7 @@ import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.BolusCalculatorResult
import info.nightscout.androidaps.database.entities.ValueWithUnit
@ -175,9 +175,9 @@ class BolusWizard @Inject constructor(
this.quickWizard = quickWizard
// Insulin from BG
sens = Profile.fromMgdlToUnits(profile.isfMgdl, profileFunction.getUnits())
targetBGLow = Profile.fromMgdlToUnits(profile.targetLowMgdl, profileFunction.getUnits())
targetBGHigh = Profile.fromMgdlToUnits(profile.targetHighMgdl, profileFunction.getUnits())
sens = Profile.fromMgdlToUnits(profile.getIsfMgdl(), profileFunction.getUnits())
targetBGLow = Profile.fromMgdlToUnits(profile.getTargetLowMgdl(), profileFunction.getUnits())
targetBGHigh = Profile.fromMgdlToUnits(profile.getTargetHighMgdl(), profileFunction.getUnits())
if (useTT && tempTarget != null) {
targetBGLow = Profile.fromMgdlToUnits(tempTarget.lowTarget, profileFunction.getUnits())
targetBGHigh = Profile.fromMgdlToUnits(tempTarget.highTarget, profileFunction.getUnits())
@ -201,7 +201,7 @@ class BolusWizard @Inject constructor(
}
// Insulin from carbs
ic = profile.ic
ic = profile.getIc()
insulinFromCarbs = carbs / ic
insulinFromCOB = if (useCob) (cob / ic) else 0.0
@ -218,7 +218,7 @@ class BolusWizard @Inject constructor(
// Insulin from superbolus for 2h. Get basal rate now and after 1h
if (useSuperBolus) {
insulinFromSuperBolus = profile.basal
insulinFromSuperBolus = profile.getBasal()
var timeAfter1h = System.currentTimeMillis()
timeAfter1h += T.hours(1).msecs()
insulinFromSuperBolus += profile.getBasal(timeAfter1h)

View file

@ -2,11 +2,12 @@ package info.nightscout.androidaps.utils.wizard
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.extensions.valueToUnits
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
@ -14,7 +15,6 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProv
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper.safeGetInt
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
import info.nightscout.androidaps.extensions.valueToUnits
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONException
import org.json.JSONObject
@ -73,7 +73,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec
return this
}
fun isActive(): Boolean = Profile.secondsFromMidnight() >= validFrom() && Profile.secondsFromMidnight() <= validTo()
fun isActive(): Boolean = profileFunction.secondsFromMidnight() >= validFrom() && profileFunction.secondsFromMidnight() <= validTo()
fun doCalc(profile: Profile, profileName: String, lastBG: GlucoseValue, _synchronized: Boolean): BolusWizard {
val dbRecord = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()

View file

@ -89,6 +89,7 @@
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/iob_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"

View file

@ -1,19 +1,44 @@
<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"
android:orientation="vertical"
tools:context="info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsProfileSwitchFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<info.nightscout.androidaps.utils.ui.SingleClickButton
android:id="@+id/refresh_from_nightscout"
style="?android:attr/buttonStyle"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:drawableStart="@drawable/ic_refresh"
android:text="@string/refresheventsfromnightscout" />
<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_removed"
app:srcCompat="@drawable/ic_visibility" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"

View file

@ -24,8 +24,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical|end"
android:paddingEnd="5dp"
android:paddingStart="10dp"
android:paddingEnd="5dp"
android:text="{fa-clock-o}"
tools:ignore="HardcodedText" />
@ -48,37 +48,9 @@
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="HardcodedText,RtlSymmetry" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:orientation="horizontal">
<TextView
android:id="@+id/duration"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="10dp"
android:text="60 min"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="HardcodedText,RtlSymmetry" />
<TextView
android:id="@+id/invalid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="10dp"
android:text="@string/invalid"
android:textAlignment="viewEnd"
android:textColor="@android:color/holo_red_light"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/ph"
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="10dp"
android:text="PH"
@ -95,12 +67,46 @@
android:textColor="@color/colorSetTempButton"
tools:ignore="HardcodedText,RtlSymmetry" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:orientation="horizontal">
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:text="60 min"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="HardcodedText,RtlSymmetry" />
<TextView
android:id="@+id/spacer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="" />
<TextView
android:id="@+id/invalid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="10dp"
android:text="@string/invalid"
android:textAlignment="viewEnd"
android:textColor="@android:color/holo_red_light"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/clone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="5dp"
android:paddingStart="10dp"
android:paddingEnd="5dp"
android:text="@string/clone_label"
android:textAlignment="viewEnd"
android:textColor="@android:color/holo_blue_light" />
@ -109,8 +115,8 @@
android:id="@+id/remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="5dp"
android:paddingStart="10dp"
android:paddingEnd="5dp"
android:text="@string/remove_button"
android:textAlignment="viewEnd"
android:textColor="@android:color/holo_orange_light" />
@ -120,10 +126,10 @@
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:background="@color/list_delimiter" />
</LinearLayout>

View file

@ -46,6 +46,7 @@
<string name="key_ns_device_status_last_synced_id" translatable="false">ns_device_status_last_synced_id</string>
<string name="key_ns_temporary_basal_last_synced_id" translatable="false">ns_temporary_basal_last_synced_id</string>
<string name="key_ns_extended_bolus_last_synced_id" translatable="false">ns_extended_bolus_last_synced_id</string>
<string name="key_ns_profile_switch_last_synced_id" translatable="false">profile_switch_last_synced_id</string>
<string name="treatmentssafety_title">Treatments safety</string>
<string name="treatmentssafety_maxbolus_title">Max allowed bolus [U]</string>

View file

@ -3,8 +3,10 @@ package info.nightscout.androidaps
import android.content.Context
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.embedments.InsulinConfiguration
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
import info.nightscout.androidaps.extensions.pureProfileFromJson
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.DateUtil
@ -31,36 +33,34 @@ open class TestBaseWithProfile : TestBase() {
lateinit var dateUtil: DateUtil
val rxBus = RxBusWrapper(aapsSchedulers)
val profileInjector = HasAndroidInjector {
AndroidInjector {
if (it is Profile) {
it.aapsLogger = aapsLogger
it.activePlugin = activePluginProvider
it.resourceHelper = resourceHelper
it.rxBus = rxBus
it.fabricPrivacy = fabricPrivacy
it.config = config
it.dateUtil = dateUtil
}
if (it is ProfileSwitch) {
it.treatmentsPlugin = treatmentsInterface
it.aapsLogger = aapsLogger
it.rxBus = rxBus
it.resourceHelper = resourceHelper
it.dateUtil = dateUtil
}
}
}
val profileInjector = HasAndroidInjector { AndroidInjector { } }
private lateinit var validProfileJSON: String
lateinit var validProfile: Profile
lateinit var validProfile: ProfileSealed.Pure
lateinit var effectiveProfileSwitch: EffectiveProfileSwitch
@Suppress("PropertyName") val TESTPROFILENAME = "someProfile"
@Before
fun prepareMock() {
validProfileJSON = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
dateUtil = DateUtil(context)
validProfile = Profile(profileInjector, JSONObject(validProfileJSON), Constants.MGDL)
validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!)
effectiveProfileSwitch = EffectiveProfileSwitch(
timestamp = dateUtil.now(),
basalBlocks = validProfile.basalBlocks,
isfBlocks = validProfile.isfBlocks,
icBlocks = validProfile.icBlocks,
targetBlocks = validProfile.targetBlocks,
glucoseUnit = EffectiveProfileSwitch.GlucoseUnit.MMOL,
originalProfileName = "",
originalCustomizedName = "",
originalTimeshift = 0,
originalPercentage = 100,
originalDuration = 0,
originalEnd = 0,
insulinConfiguration = InsulinConfiguration("", 0, 0)
)
}
fun getValidProfileStore(): ProfileStore {
@ -69,6 +69,6 @@ open class TestBaseWithProfile : TestBase() {
store.put(TESTPROFILENAME, JSONObject(validProfileJSON))
json.put("defaultProfile", TESTPROFILENAME)
json.put("store", store)
return ProfileStore(profileInjector, json)
return ProfileStore(profileInjector, json, dateUtil)
}
}

View file

@ -2,7 +2,7 @@ package info.nightscout.androidaps
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.interfaces.Pump

View file

@ -4,10 +4,8 @@ import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.utils.sharedPreferences.SP
import info.nightscout.androidaps.utils.wizard.QuickWizard
import info.nightscout.androidaps.utils.wizard.QuickWizardEntry
@ -15,20 +13,14 @@ import org.json.JSONArray
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.powermock.api.mockito.PowerMockito
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class)
@PrepareForTest(Profile::class, IobCobCalculatorPlugin::class)
class QuickWizardTest : TestBase() {
@Mock lateinit var sp: SP
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var treatmentsPlugin: TreatmentsPlugin
@Mock lateinit var loopPlugin: LoopPlugin
private val data1 = "{\"buttonText\":\"Meal\",\"carbs\":36,\"validFrom\":0,\"validTo\":18000," +
@ -52,8 +44,7 @@ class QuickWizardTest : TestBase() {
@Before
fun mock() {
PowerMockito.mockStatic(Profile::class.java)
PowerMockito.`when`<Any>(Profile::class.java, "secondsFromMidnight").thenReturn(0)
PowerMockito.`when`(profileFunction.secondsFromMidnight()).thenReturn(0)
`when`(sp.getString(R.string.key_quickwizard, "[]")).thenReturn("[]")
quickWizard = QuickWizard(sp, injector)
}

View file

@ -1,6 +1,7 @@
package info.nightscout.androidaps.data.defaultProfile
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.TestBaseWithProfile
import org.junit.Assert.assertEquals
import org.junit.Test
@ -9,18 +10,19 @@ class DefaultProfileTest : TestBaseWithProfile() {
@Test
fun profile() {
var p = DefaultProfile(profileInjector).profile(5.0, 5.1 / 0.3, 0.0, Constants.MMOL)
assertEquals(0.150, p!!.getBasalTimeFromMidnight(0), 0.001)
val dp = DefaultProfile(dateUtil).profile(5.0, 5.1 / 0.3, 0.0, GlucoseUnit.MMOL)
var p = ProfileSealed.Pure(dp!!)
assertEquals(0.150, p.getBasalTimeFromMidnight(0), 0.001)
assertEquals(15.0, p.getIcTimeFromMidnight(0), 0.001)
assertEquals(11.8, p.getIsfTimeFromMidnight(0), 0.001)
p = DefaultProfile(profileInjector).profile(7.0, 10.0 / 0.4, 0.0, Constants.MMOL)
assertEquals(0.350, p!!.getBasalTimeFromMidnight(0), 0.001)
p = ProfileSealed.Pure(DefaultProfile(dateUtil).profile(7.0, 10.0 / 0.4, 0.0, GlucoseUnit.MMOL)!!)
assertEquals(0.350, p.getBasalTimeFromMidnight(0), 0.001)
assertEquals(15.0, p.getIcTimeFromMidnight(0), 0.001)
assertEquals(6.8, p.getIsfTimeFromMidnight(0), 0.001)
p = DefaultProfile(profileInjector).profile(12.0, 25.0 / 0.5, 0.0, Constants.MMOL)
assertEquals(0.80, p!!.getBasalTimeFromMidnight(0), 0.001)
p = ProfileSealed.Pure(DefaultProfile(dateUtil).profile(12.0, 25.0 / 0.5, 0.0, GlucoseUnit.MMOL)!!)
assertEquals(0.80, p.getBasalTimeFromMidnight(0), 0.001)
assertEquals(10.0, p.getIcTimeFromMidnight(0), 0.001)
assertEquals(2.2, p.getIsfTimeFromMidnight(0), 0.001)
}

View file

@ -14,11 +14,7 @@ import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
@ -162,7 +158,6 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
}.`when`(commandQueue).extendedBolus(ArgumentMatchers.anyDouble(), ArgumentMatchers.anyInt(), ArgumentMatchers.any(Callback::class.java))
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
`when`(activePlugin.activeTreatments).thenReturn(treatmentsInterface)
`when`(virtualPumpPlugin.shortStatus(ArgumentMatchers.anyBoolean())).thenReturn("Virtual Pump")
`when`(virtualPumpPlugin.isSuspended()).thenReturn(false)
@ -171,11 +166,10 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(0))
`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(0))
`when`(treatmentsInterface.service).thenReturn(treatmentService)
`when`(activePlugin.activeProfileSource).thenReturn(localProfilePlugin)
`when`(profileFunction.getUnits()).thenReturn(Constants.MGDL)
`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
`when`(otp.name()).thenReturn("User")
`when`(otp.checkOTP(ArgumentMatchers.anyString())).thenReturn(OneTimePasswordValidationResult.OK)

View file

@ -41,7 +41,7 @@ class TreatmentsPluginTest : TestBaseWithProfile() {
}
}
@Test fun dumy() {}
@Test fun dummy() {}
/*
private lateinit var insulinOrefRapidActingPlugin: InsulinOrefRapidActingPlugin
private lateinit var sot: TreatmentsPlugin

View file

@ -2,15 +2,14 @@ package info.nightscout.androidaps.queue
import android.content.Context
import android.os.PowerManager
import dagger.Lazy
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.utils.buildHelper.ConfigImpl
import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Constraint
@ -27,15 +26,18 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.buildHelper.ConfigImpl
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.Single
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyLong
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner
import java.util.*
@ -48,7 +50,6 @@ import java.util.*
class CommandQueueTest : TestBaseWithProfile() {
@Mock lateinit var constraintChecker: ConstraintChecker
@Mock lateinit var lazyActivePlugin: Lazy<ActivePlugin>
@Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var sp: SP
@Mock lateinit var loggerUtils: LoggerUtils
@ -63,7 +64,7 @@ class CommandQueueTest : TestBaseWithProfile() {
resourceHelper: ResourceHelper,
constraintChecker: ConstraintChecker,
profileFunction: ProfileFunction,
activePlugin: Lazy<ActivePlugin>,
activePlugin: ActivePlugin,
context: Context,
sp: SP,
buildHelper: BuildHelper,
@ -106,15 +107,14 @@ class CommandQueueTest : TestBaseWithProfile() {
@Before
fun prepare() {
commandQueue = CommandQueueMocked(injector, aapsLogger, rxBus, aapsSchedulers, resourceHelper, constraintChecker, profileFunction, lazyActivePlugin, context, sp, BuildHelper(ConfigImpl(), loggerUtils), dateUtil, repository, fabricPrivacy)
commandQueue = CommandQueueMocked(injector, aapsLogger, rxBus, aapsSchedulers, resourceHelper, constraintChecker, profileFunction, activePlugin, context, sp, BuildHelper(ConfigImpl(), loggerUtils), dateUtil, repository, fabricPrivacy)
testPumpPlugin = TestPumpPlugin(injector)
testPumpPlugin.pumpDescription.basalMinimumRate = 0.1
`when`(context.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager)
`when`(lazyActivePlugin.get()).thenReturn(activePlugin)
`when`(activePlugin.activePump).thenReturn(testPumpPlugin)
`when`(activePlugin.activeTreatments).thenReturn(treatmentsInterface)
`when`(repository.getEffectiveProfileSwitchActiveAt(anyLong())).thenReturn(Single.just(ValueWrapper.Existing(effectiveProfileSwitch)))
`when`(repository.getLastBolusRecord()).thenReturn(
Bolus(
timestamp = Calendar.getInstance().also { it.set(2000, 0, 1) }.timeInMillis,
@ -138,7 +138,7 @@ class CommandQueueTest : TestBaseWithProfile() {
@Test
fun commandIsPickedUp() {
val commandQueue = CommandQueue(injector, aapsLogger, rxBus, aapsSchedulers, resourceHelper, constraintChecker, profileFunction, lazyActivePlugin, context, sp, BuildHelper(ConfigImpl(), loggerUtils), dateUtil, repository, fabricPrivacy)
val commandQueue = CommandQueue(injector, aapsLogger, rxBus, aapsSchedulers, resourceHelper, constraintChecker, profileFunction, activePlugin, context, sp, BuildHelper(ConfigImpl(), loggerUtils), dateUtil, repository, fabricPrivacy)
// start with empty queue
Assert.assertEquals(0, commandQueue.size())
@ -365,7 +365,7 @@ class CommandQueueTest : TestBaseWithProfile() {
// when
testPumpPlugin.isProfileSet = true
commandQueue.setProfile(validProfile, object : Callback() {
commandQueue.setProfile(validProfile, false, object : Callback() {
override fun run() {
Assert.assertTrue(result.success)
Assert.assertFalse(result.enacted)
@ -377,7 +377,7 @@ class CommandQueueTest : TestBaseWithProfile() {
Assert.assertEquals(0, commandQueue.size())
// different should be added
testPumpPlugin.isProfileSet = false
commandQueue.setProfile(validProfile, object : Callback() {
commandQueue.setProfile(validProfile, false, object : Callback() {
override fun run() {
Assert.assertTrue(result.success)
Assert.assertTrue(result.enacted)
@ -385,7 +385,7 @@ class CommandQueueTest : TestBaseWithProfile() {
})
Assert.assertEquals(1, commandQueue.size())
// next should be ignored
commandQueue.setProfile(validProfile, object : Callback() {
commandQueue.setProfile(validProfile, false, object : Callback() {
override fun run() {
Assert.assertTrue(result.success)
}

View file

@ -2,10 +2,8 @@ package info.nightscout.androidaps.queue
import android.content.Context
import android.os.PowerManager
import dagger.Lazy
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.utils.buildHelper.ConfigImpl
import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.database.AppRepository
@ -22,6 +20,7 @@ import info.nightscout.androidaps.queue.commands.CommandTempBasalAbsolute
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.buildHelper.ConfigImpl
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Assert
import org.junit.Before
@ -39,7 +38,6 @@ import org.powermock.modules.junit4.PowerMockRunner
class QueueThreadTest : TestBaseWithProfile() {
@Mock lateinit var constraintChecker: ConstraintChecker
@Mock lateinit var lazyActivePlugin: Lazy<ActivePlugin>
@Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var sp: SP
@Mock lateinit var loggerUtils: LoggerUtils
@ -65,16 +63,13 @@ class QueueThreadTest : TestBaseWithProfile() {
@Before
fun prepare() {
pumpPlugin = TestPumpPlugin(injector)
commandQueue = CommandQueue(injector, aapsLogger, rxBus, aapsSchedulers, resourceHelper, constraintChecker, profileFunction, lazyActivePlugin, context, sp, BuildHelper(ConfigImpl(), loggerUtils), dateUtil, repository, fabricPrivacy)
commandQueue = CommandQueue(injector, aapsLogger, rxBus, aapsSchedulers, resourceHelper, constraintChecker, profileFunction, activePlugin, context, sp, BuildHelper(ConfigImpl(), loggerUtils), dateUtil, repository, fabricPrivacy)
val pumpDescription = PumpDescription()
pumpDescription.basalMinimumRate = 0.1
Mockito.`when`(context.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager)
Mockito.`when`(lazyActivePlugin.get()).thenReturn(activePlugin)
Mockito.`when`(activePlugin.activePump).thenReturn(pumpPlugin)
Mockito.`when`(activePlugin.activeTreatments).thenReturn(treatmentsInterface)
// Mockito.`when`(treatmentsInterface.lastBolusTime).thenReturn(Calendar.getInstance().also { it.set(2000, 0, 1) }.timeInMillis)
Mockito.`when`(profileFunction.getProfile()).thenReturn(validProfile)
val bolusConstraint = Constraint(0.0)

View file

@ -3,11 +3,10 @@ package info.nightscout.androidaps.utils.wizard
import android.content.Context
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
@ -66,12 +65,12 @@ class BolusWizardTest : TestBase() {
@Suppress("SameParameterValue")
private fun setupProfile(targetLow: Double, targetHigh: Double, insulinSensitivityFactor: Double, insulinToCarbRatio: Double): Profile {
val profile = Mockito.mock(Profile::class.java)
`when`(profile.targetLowMgdl).thenReturn(targetLow)
`when`(profile.targetHighMgdl).thenReturn(targetHigh)
`when`(profile.isfMgdl).thenReturn(insulinSensitivityFactor)
`when`(profile.ic).thenReturn(insulinToCarbRatio)
`when`(profile.getTargetLowMgdl()).thenReturn(targetLow)
`when`(profile.getTargetLowMgdl()).thenReturn(targetHigh)
`when`(profile.getIsfMgdl()).thenReturn(insulinSensitivityFactor)
`when`(profile.getIc()).thenReturn(insulinToCarbRatio)
`when`(profileFunction.getUnits()).thenReturn(Constants.MGDL)
`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
`when`(activePlugin.activeTreatments).thenReturn(treatmentsPlugin)
`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(System.currentTimeMillis()))
`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(System.currentTimeMillis()))

View file

@ -62,7 +62,7 @@ class ActionProfileSwitch(injector: HasAndroidInjector) : Action(injector) {
uel.log(UserEntry.Action.PROFILE_SWITCH, Sources.Automation, title,
ValueWithUnit.SimpleString(inputProfileName.value),
ValueWithUnit.Percent(100))
activePlugin.activeTreatments.doProfileSwitch(profileStore, inputProfileName.value, 0, 100, 0, dateUtil.now())
profileFunction.createProfileSwitch(profileStore, inputProfileName.value, 0, 100, 0, dateUtil.now())
callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run()
}

View file

@ -8,7 +8,7 @@ import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration
@ -23,8 +23,9 @@ import org.json.JSONObject
import javax.inject.Inject
class ActionProfileSwitchPercent(injector: HasAndroidInjector) : Action(injector) {
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var uel: UserEntryLogger
var pct = InputPercent()
@ -45,7 +46,7 @@ class ActionProfileSwitchPercent(injector: HasAndroidInjector) : Action(injector
uel.log(UserEntry.Action.PROFILE_SWITCH, Sources.Automation, title + ": " + resourceHelper.gs(R.string.startprofile, pct.value.toInt(), duration.value),
ValueWithUnit.Percent(pct.value.toInt()),
ValueWithUnit.Minute(duration.value))
activePlugin.activeTreatments.doProfileSwitch(duration.value, pct.value.toInt(), 0)
profileFunction.createProfileSwitch(duration.value, pct.value.toInt(), 0)
callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run()
}

View file

@ -5,7 +5,7 @@ import androidx.annotation.DrawableRes
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.automation.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TemporaryTarget
@ -28,6 +28,7 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.JsonHelper.safeGetDouble
import info.nightscout.androidaps.extensions.friendlyDescription
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.utils.resources.ResourceHelper
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
@ -75,7 +76,7 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
}
override fun generateDialog(root: LinearLayout) {
val unitResId = if (value.units == Constants.MGDL) R.string.mgdl else R.string.mmol
val unitResId = if (value.units == GlucoseUnit.MGDL) R.string.mgdl else R.string.mmol
LayoutBuilder()
.add(LabelWithElement(resourceHelper, resourceHelper.gs(R.string.careportal_temporarytarget) + "\n[" + resourceHelper.gs(unitResId) + "]", "", value))
.add(LabelWithElement(resourceHelper, resourceHelper.gs(R.string.duration_min_label), "", duration))
@ -89,7 +90,7 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
override fun toJSON(): String {
val data = JSONObject()
.put("value", value.value)
.put("units", value.units)
.put("units", value.units.asText)
.put("durationInMinutes", duration.getMinutes())
return JSONObject()
.put("type", this.javaClass.name)
@ -99,7 +100,7 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
override fun fromJSON(data: String): Action {
val o = JSONObject(data)
value.units = JsonHelper.safeGetString(o, "units", Constants.MGDL)
value.units = GlucoseUnit.fromText(JsonHelper.safeGetString(o, "units", Constants.MGDL))
value.value = safeGetDouble(o, "value")
duration.setMinutes(JsonHelper.safeGetInt(o, "durationInMinutes"))
return this
@ -114,7 +115,7 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
)
override fun isValid(): Boolean =
if (value.units == Constants.MMOL) { // mmol
if (value.units == GlucoseUnit.MMOL) { // mmol
value.value >= Constants.MIN_TT_MMOL &&
value.value <= Constants.MAX_TT_MMOL &&
duration.value > 0

View file

@ -1,22 +1,22 @@
package info.nightscout.androidaps.plugins.general.automation.elements
import android.widget.LinearLayout
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.automation.R
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.utils.ui.NumberPicker
import java.text.DecimalFormat
class InputBg(profileFunction: ProfileFunction) : Element() {
var units = Constants.MGDL
var units = GlucoseUnit.MGDL
var value = 0.0
var minValue = 0.0
private var maxValue = 0.0
private var step = 0.0
private var decimalFormat: DecimalFormat? = null
constructor(profileFunction: ProfileFunction, value: Double, units: String) : this(profileFunction) {
constructor(profileFunction: ProfileFunction, value: Double, units: GlucoseUnit) : this(profileFunction) {
setUnits(units)
this.value = value
}
@ -37,8 +37,8 @@ class InputBg(profileFunction: ProfileFunction) : Element() {
return this
}
fun setUnits(units: String): InputBg {
if (units == Constants.MMOL) {
fun setUnits(units: GlucoseUnit): InputBg {
if (units == GlucoseUnit.MMOL) {
minValue = MMOL_MIN
maxValue = MMOL_MAX
step = 0.1

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