commit
66ec1d05ea
25 changed files with 1017 additions and 47 deletions
|
@ -226,6 +226,8 @@ dependencies {
|
|||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'com.google.android.gms:play-services-wearable:17.0.0'
|
||||
implementation 'com.google.firebase:firebase-core:17.2.1'
|
||||
implementation 'com.google.firebase:firebase-auth:19.2.0'
|
||||
implementation 'com.google.firebase:firebase-database:19.2.0'
|
||||
implementation('com.crashlytics.sdk.android:crashlytics:2.10.1@aar') {
|
||||
transitive = true;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,12 @@
|
|||
"package_name": "info.nightscout.aapspumpcontrol"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||
|
@ -37,7 +42,12 @@
|
|||
"package_name": "info.nightscout.androidaps"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||
|
@ -61,7 +71,12 @@
|
|||
"package_name": "info.nightscout.nsclient"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||
|
@ -85,7 +100,12 @@
|
|||
"package_name": "info.nightscout.nsclient2"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||
|
|
|
@ -76,6 +76,8 @@
|
|||
</activity>
|
||||
<activity android:name=".plugins.pump.danaRS.activities.PairingHelperActivity" />
|
||||
<activity android:name=".activities.HistoryBrowseActivity" />
|
||||
<activity android:name=".activities.SurveyActivity" />
|
||||
<activity android:name=".activities.StatsActivity" />
|
||||
|
||||
<!-- Receive new BG readings from other local apps -->
|
||||
<receiver
|
||||
|
|
|
@ -41,6 +41,8 @@ import info.nightscout.androidaps.activities.HistoryBrowseActivity;
|
|||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
|
||||
import info.nightscout.androidaps.activities.PreferencesActivity;
|
||||
import info.nightscout.androidaps.activities.SingleFragmentActivity;
|
||||
import info.nightscout.androidaps.activities.StatsActivity;
|
||||
import info.nightscout.androidaps.activities.SurveyActivity;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.events.EventRebuildTabs;
|
||||
|
@ -343,6 +345,14 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
|||
startActivity(i);
|
||||
}, null);
|
||||
return true;
|
||||
/*
|
||||
case R.id.nav_survey:
|
||||
startActivity(new Intent(this, SurveyActivity.class));
|
||||
return true;
|
||||
*/
|
||||
case R.id.nav_stats:
|
||||
startActivity(new Intent(this, StatsActivity.class));
|
||||
return true;
|
||||
}
|
||||
return actionBarDrawerToggle.onOptionsItemSelected(item);
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.receivers.DBAccessRec
|
|||
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
|
||||
import info.nightscout.androidaps.utils.ActivityMonitor;
|
||||
import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin;
|
||||
import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin;
|
||||
|
@ -145,6 +146,8 @@ public class MainApp extends Application {
|
|||
log.error("Error with Fabric init! " + e);
|
||||
}
|
||||
|
||||
registerActivityLifecycleCallbacks(ActivityMonitor.INSTANCE);
|
||||
|
||||
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
|
||||
mFirebaseAnalytics.setAnalyticsCollectionEnabled(!Boolean.getBoolean("disableFirebase"));
|
||||
|
||||
|
@ -430,7 +433,7 @@ public class MainApp extends Application {
|
|||
if (timeDateOrTZChangeReceiver != null) {
|
||||
unregisterReceiver(timeDateOrTZChangeReceiver);
|
||||
}
|
||||
|
||||
unregisterActivityLifecycleCallbacks(ActivityMonitor.INSTANCE);
|
||||
}
|
||||
|
||||
public static int dpToPx(int dp) {
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package info.nightscout.androidaps.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.ActivityMonitor
|
||||
import info.nightscout.androidaps.utils.OKDialog
|
||||
import info.nightscout.androidaps.utils.TddCalculator
|
||||
import info.nightscout.androidaps.utils.TirCalculator
|
||||
import kotlinx.android.synthetic.main.stats_activity.*
|
||||
|
||||
|
||||
class StatsActivity : NoSplashAppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.stats_activity)
|
||||
|
||||
stats_tdds.text = TddCalculator.stats()
|
||||
stats_tir.text = TirCalculator.stats()
|
||||
stats_activity.text = ActivityMonitor.stats()
|
||||
|
||||
ok.setOnClickListener { finish() }
|
||||
stats_reset.setOnClickListener {
|
||||
OKDialog.showConfirmation(this, MainApp.gs(R.string.doyouwantresetstats)) {
|
||||
ActivityMonitor.reset()
|
||||
recreate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
package info.nightscout.androidaps.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.ArrayAdapter
|
||||
import com.google.firebase.auth.FirebaseAuth
|
||||
import com.google.firebase.database.FirebaseDatabase
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.defaultProfile.DefaultProfile
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||
import info.nightscout.androidaps.plugins.treatments.fragments.ProfileViewerDialog
|
||||
import info.nightscout.androidaps.utils.*
|
||||
import kotlinx.android.synthetic.main.survey_fragment.*
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.util.*
|
||||
|
||||
|
||||
class SurveyActivity : NoSplashAppCompatActivity() {
|
||||
private val log = LoggerFactory.getLogger(SurveyActivity::class.java)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.survey_fragment)
|
||||
|
||||
survey_id.text = InstanceId.instanceId()
|
||||
|
||||
val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile
|
||||
val profileList = profileStore?.getProfileList() ?: return
|
||||
survey_spinner.adapter = ArrayAdapter(this, R.layout.spinner_centered, profileList)
|
||||
|
||||
survey_tdds.text = TddCalculator.stats()
|
||||
survey_tir.text = TirCalculator.stats()
|
||||
survey_activity.text = ActivityMonitor.stats()
|
||||
|
||||
survey_profile.setOnClickListener {
|
||||
val age = SafeParse.stringToDouble(survey_age.text.toString())
|
||||
val weight = SafeParse.stringToDouble(survey_weight.text.toString())
|
||||
val tdd = SafeParse.stringToDouble(survey_tdd.text.toString())
|
||||
if (age < 1 || age > 120) {
|
||||
ToastUtils.showToastInUiThread(this, R.string.invalidage)
|
||||
return@setOnClickListener
|
||||
}
|
||||
if ((weight < 5 || weight > 150) && tdd == 0.0) {
|
||||
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
|
||||
return@setOnClickListener
|
||||
}
|
||||
if ((tdd < 5 || tdd > 150) && weight == 0.0) {
|
||||
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
|
||||
return@setOnClickListener
|
||||
}
|
||||
val profile = DefaultProfile().profile(age, tdd, weight, ProfileFunctions.getSystemUnits())
|
||||
val args = Bundle()
|
||||
args.putLong("time", DateUtil.now())
|
||||
args.putInt("mode", ProfileViewerDialog.Mode.CUSTOM_PROFILE.ordinal)
|
||||
args.putString("customProfile", profile.data.toString())
|
||||
args.putString("customProfileUnits", profile.units)
|
||||
args.putString("customProfileName", "Age: $age TDD: $tdd Weight: $weight")
|
||||
val pvd = ProfileViewerDialog()
|
||||
pvd.arguments = args
|
||||
pvd.show(supportFragmentManager, "ProfileViewDialog")
|
||||
}
|
||||
|
||||
survey_submit.setOnClickListener {
|
||||
val r = FirebaseRecord()
|
||||
r.id = InstanceId.instanceId()
|
||||
r.age = SafeParse.stringToInt(survey_age.text.toString())
|
||||
r.weight = SafeParse.stringToInt(survey_weight.text.toString())
|
||||
if (r.age < 1 || r.age > 120) {
|
||||
ToastUtils.showToastInUiThread(this, R.string.invalidage)
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (r.weight < 5 || r.weight > 150) {
|
||||
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
if (survey_spinner.selectedItem == null)
|
||||
return@setOnClickListener
|
||||
val profileName = survey_spinner.selectedItem.toString()
|
||||
val specificProfile = profileStore.getSpecificProfile(profileName)
|
||||
|
||||
r.profileJson = specificProfile.toString()
|
||||
|
||||
val auth = FirebaseAuth.getInstance()
|
||||
auth.signInAnonymously()
|
||||
.addOnCompleteListener(this) { task ->
|
||||
if (task.isSuccessful) {
|
||||
log.debug("signInAnonymously:success")
|
||||
val user = auth.currentUser
|
||||
|
||||
val database = FirebaseDatabase.getInstance().reference
|
||||
database.child("survey").child(r.id).setValue(r)
|
||||
} else {
|
||||
log.error("signInAnonymously:failure", task.exception)
|
||||
ToastUtils.showToastInUiThread(this, "Authentication failed.")
|
||||
//updateUI(null)
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
inner class FirebaseRecord {
|
||||
var id = ""
|
||||
var age: Int = 0
|
||||
var weight: Int = 0
|
||||
var profileJson = "ghfg"
|
||||
}
|
||||
|
||||
}
|
|
@ -397,7 +397,7 @@ public class Profile {
|
|||
return toMgdl(getIsfTimeFromMidnight(secondsFromMidnight(time)), units);
|
||||
}
|
||||
|
||||
double getIsfTimeFromMidnight(int timeAsSeconds) {
|
||||
public double getIsfTimeFromMidnight(int timeAsSeconds) {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(isf);
|
||||
return getValueToTime(isf_v, timeAsSeconds);
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
package info.nightscout.androidaps.data.defaultProfile
|
||||
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.utils.Round
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
|
||||
class DefaultProfile {
|
||||
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()
|
||||
|
||||
fun profile(age: Double, tdd: Double, weight: Double, units: String): Profile {
|
||||
val profile = JSONObject()
|
||||
if (age >= 1 && age < 6) {
|
||||
val _tdd = if (tdd == 0.0) 0.6 * weight else tdd
|
||||
closest(oneToFive, _tdd * 0.3)?.let { array -> profile.put("basal", arrayToJson(array)) }
|
||||
val ic = Round.roundTo(250.0 / _tdd, 1.0)
|
||||
profile.put("carbratio", singleValueArray(ic, arrayOf( 0.0, -4.0, -1.0, -2.0, -4.0, 0.0, -4.0)))
|
||||
val isf = Round.roundTo(200.0 / _tdd, 0.1)
|
||||
profile.put("sens", singleValueArray(isf, arrayOf( 0.0, -2.0, -0.0, -0.0, -2.0, 0.0, -2.0)))
|
||||
} else if (age >= 6 && age < 12) {
|
||||
val _tdd = if (tdd == 0.0) 0.8 * weight else tdd
|
||||
closest(sixToEleven, _tdd * 0.4)?.let { array -> profile.put("basal", arrayToJson(array)) }
|
||||
val ic = Round.roundTo(375.0 / _tdd, 1.0)
|
||||
profile.put("carbratio", singleValueArray(ic, arrayOf( 0.0, -3.0, 0.0, -1.0, -3.0, 0.0, -2.0)))
|
||||
val isf = Round.roundTo(170.0 / _tdd, 0.1)
|
||||
profile.put("sens", singleValueArray(isf, arrayOf( 0.0, -1.0, -0.0, -0.0, -1.0, 0.0, -1.0)))
|
||||
} else if (age >= 12 && age < 17) {
|
||||
val _tdd = if (tdd == 0.0) 1.0 * weight else tdd
|
||||
closest(twelveToSeventeen, _tdd * 0.5)?.let { array -> profile.put("basal", arrayToJson(array)) }
|
||||
val ic = Round.roundTo(500.0 / _tdd, 1.0)
|
||||
profile.put("carbratio", singleValueArray(ic, arrayOf( 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0)))
|
||||
val isf = Round.roundTo(100.0 / _tdd, 0.1)
|
||||
profile.put("sens", singleValueArray(isf, arrayOf( 0.2, 0.0, 0.2, 0.2, 0.0, 0.2, 0.2)))
|
||||
} else if (age >= 18) {
|
||||
|
||||
}
|
||||
profile.put("dia", 5.0)
|
||||
profile.put("carbs_hr", 20) // not used
|
||||
profile.put("delay", 5.0) // not used
|
||||
profile.put("timezone", TimeZone.getDefault().getID())
|
||||
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))))
|
||||
return Profile(profile, units)
|
||||
}
|
||||
|
||||
init {
|
||||
oneToFive[1.00] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050)
|
||||
oneToFive[1.13] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050)
|
||||
oneToFive[1.25] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.050, 0.050)
|
||||
oneToFive[1.38] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.050, 0.050)
|
||||
oneToFive[1.50] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.050, 0.050, 0.050, 0.075, 0.100, 0.100, 0.050, 0.050)
|
||||
oneToFive[1.75] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.050, 0.050, 0.050, 0.060, 0.060, 0.075, 0.075, 0.050, 0.050, 0.050, 0.100, 0.125, 0.100, 0.050, 0.050)
|
||||
oneToFive[2.00] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.075, 0.050, 0.050, 0.065, 0.065, 0.075, 0.075, 0.050, 0.050, 0.050, 0.100, 0.125, 0.100, 0.050, 0.050)
|
||||
oneToFive[2.25] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.100, 0.100, 0.075, 0.060, 0.060, 0.070, 0.070, 0.100, 0.100, 0.050, 0.050, 0.050, 0.125, 0.150, 0.125, 0.065, 0.050)
|
||||
oneToFive[2.50] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.125, 0.125, 0.100, 0.065, 0.065, 0.075, 0.075, 0.125, 0.125, 0.060, 0.060, 0.060, 0.150, 0.150, 0.150, 0.070, 0.060)
|
||||
oneToFive[2.75] = arrayOf(0.075, 0.075, 0.075, 0.100, 0.100, 0.100, 0.125, 0.150, 0.125, 0.100, 0.070, 0.070, 0.080, 0.080, 0.150, 0.150, 0.070, 0.070, 0.070, 0.175, 0.175, 0.175, 0.080, 0.070)
|
||||
oneToFive[3.25] = arrayOf(0.100, 0.100, 0.100, 0.125, 0.125, 0.125, 0.150, 0.150, 0.150, 0.100, 0.080, 0.080, 0.100, 0.100, 0.175, 0.175, 0.075, 0.075, 0.075, 0.200, 0.200, 0.200, 0.090, 0.080)
|
||||
oneToFive[3.75] = arrayOf(0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.175, 0.175, 0.175, 0.100, 0.085, 0.085, 0.110, 0.110, 0.185, 0.185, 0.080, 0.080, 0.080, 0.225, 0.225, 0.225, 0.100, 0.090)
|
||||
oneToFive[4.25] = arrayOf(0.125, 0.125, 0.130, 0.140, 0.140, 0.140, 0.200, 0.200, 0.200, 0.125, 0.090, 0.090, 0.120, 0.120, 0.200, 0.200, 0.100, 0.100, 0.100, 0.250, 0.250, 0.250, 0.125, 0.100)
|
||||
oneToFive[4.75] = arrayOf(0.125, 0.130, 0.135, 0.150, 0.150, 0.150, 0.200, 0.225, 0.200, 0.125, 0.100, 0.100, 0.125, 0.125, 0.250, 0.200, 0.110, 0.125, 0.125, 0.275, 0.275, 0.275, 0.130, 0.125)
|
||||
oneToFive[5.25] = arrayOf(0.150, 0.150, 0.150, 0.170, 0.170, 0.170, 0.225, 0.225, 0.225, 0.130, 0.125, 0.125, 0.140, 0.140, 0.250, 0.250, 0.150, 0.150, 0.150, 0.300, 0.300, 0.300, 0.150, 0.150)
|
||||
oneToFive[6.00] = arrayOf(0.170, 0.170, 0.175, 0.200, 0.200, 0.200, 0.250, 0.250, 0.250, 0.150, 0.125, 0.125, 0.150, 0.150, 0.275, 0.275, 0.170, 0.150, 0.150, 0.350, 0.350, 0.350, 0.175, 0.150)
|
||||
oneToFive[6.75] = arrayOf(0.200, 0.200, 0.200, 0.225, 0.225, 0.225, 0.275, 0.275, 0.275, 0.200, 0.130, 0.130, 0.175, 0.175, 0.300, 0.300, 0.170, 0.175, 0.175, 0.375, 0.375, 0.375, 0.200, 0.175)
|
||||
oneToFive[7.50] = arrayOf(0.225, 0.230, 0.235, 0.250, 0.250, 0.250, 0.300, 0.300, 0.300, 0.250, 0.150, 0.150, 0.200, 0.200, 0.325, 0.325, 0.200, 0.200, 0.200, 0.400, 0.450, 0.400, 0.350, 0.200)
|
||||
|
||||
sixToEleven[5.26] = arrayOf(0.18, 0.18, 0.18, 0.20, 0.20, 0.23, 0.25, 0.25, 0.25, 0.18, 0.15, 0.13, 0.15, 0.15, 0.25, 0.25, 0.20, 0.15, 0.18, 0.25, 0.25, 0.25, 0.23, 0.20)
|
||||
sixToEleven[5.61] = arrayOf(0.18, 0.20, 0.20, 0.23, 0.23, 0.25, 0.28, 0.28, 0.25, 0.20, 0.15, 0.13, 0.15, 0.18, 0.25, 0.25, 0.20, 0.15, 0.18, 0.28, 0.25, 0.25, 0.23, 0.20)
|
||||
sixToEleven[5.93] = arrayOf(0.20, 0.20, 0.23, 0.25, 0.25, 0.25, 0.30, 0.30, 0.30, 0.25, 0.15, 0.15, 0.18, 0.18, 0.28, 0.28, 0.20, 0.20, 0.20, 0.28, 0.28, 0.28, 0.25, 0.23)
|
||||
sixToEleven[6.26] = arrayOf(0.20, 0.23, 0.23, 0.25, 0.25, 0.28, 0.33, 0.30, 0.30, 0.25, 0.18, 0.15, 0.18, 0.18, 0.28, 0.28, 0.23, 0.20, 0.20, 0.28, 0.30, 0.28, 0.25, 0.23)
|
||||
sixToEleven[6.60] = arrayOf(0.23, 0.23, 0.25, 0.25, 0.25, 0.28, 0.33, 0.33, 0.33, 0.28, 0.18, 0.15, 0.18, 0.18, 0.30, 0.28, 0.23, 0.23, 0.20, 0.30, 0.30, 0.30, 0.25, 0.25)
|
||||
sixToEleven[7.26] = arrayOf(0.23, 0.25, 0.28, 0.28, 0.30, 0.33, 0.38, 0.35, 0.35, 0.30, 0.18, 0.18, 0.18, 0.19, 0.33, 0.30, 0.25, 0.23, 0.23, 0.33, 0.33, 0.33, 0.30, 0.25)
|
||||
sixToEleven[7.92] = arrayOf(0.25, 0.25, 0.28, 0.30, 0.33, 0.35, 0.38, 0.38, 0.38, 0.35, 0.20, 0.20, 0.23, 0.25, 0.35, 0.33, 0.30, 0.25, 0.25, 0.35, 0.35, 0.35, 0.33, 0.28)
|
||||
sixToEleven[8.57] = arrayOf(0.28, 0.28, 0.30, 0.30, 0.33, 0.38, 0.40, 0.43, 0.40, 0.38, 0.25, 0.25, 0.25, 0.28, 0.38, 0.38, 0.33, 0.28, 0.28, 0.38, 0.40, 0.38, 0.35, 0.30)
|
||||
sixToEleven[9.24] = arrayOf(0.30, 0.33, 0.35, 0.38, 0.40, 0.40, 0.43, 0.45, 0.43, 0.40, 0.30, 0.25, 0.28, 0.28, 0.38, 0.40, 0.33, 0.30, 0.30, 0.40, 0.43, 0.40, 0.38, 0.35)
|
||||
sixToEleven[9.89] = arrayOf(0.35, 0.35, 0.38, 0.40, 0.40, 0.43, 0.45, 0.48, 0.45, 0.40, 0.30, 0.25, 0.28, 0.30, 0.40, 0.43, 0.35, 0.33, 0.33, 0.43, 0.45, 0.43, 0.40, 0.38)
|
||||
sixToEleven[10.56] = arrayOf(0.38, 0.38, 0.40, 0.43, 0.45, 0.45, 0.48, 0.50, 0.48, 0.40, 0.35, 0.25, 0.30, 0.33, 0.43, 0.45, 0.35, 0.35, 0.35, 0.45, 0.48, 0.45, 0.43, 0.40)
|
||||
sixToEleven[11.21] = arrayOf(0.40, 0.43, 0.43, 0.45, 0.48, 0.50, 0.53, 0.55, 0.50, 0.40, 0.35, 0.30, 0.33, 0.33, 0.45, 0.48, 0.38, 0.35, 0.37, 0.50, 0.50, 0.48, 0.45, 0.43)
|
||||
sixToEleven[11.88] = arrayOf(0.43, 0.43, 0.45, 0.45, 0.48, 0.50, 0.55, 0.58, 0.50, 0.40, 0.35, 0.33, 0.33, 0.33, 0.48, 0.50, 0.40, 0.38, 0.38, 0.53, 0.53, 0.50, 0.48, 0.45)
|
||||
sixToEleven[12.53] = arrayOf(0.45, 0.45, 0.48, 0.50, 0.53, 0.55, 0.60, 0.60, 0.60, 0.45, 0.40, 0.35, 0.35, 0.38, 0.50, 0.53, 0.40, 0.38, 0.38, 0.55, 0.58, 0.55, 0.50, 0.48)
|
||||
sixToEleven[13.19] = arrayOf(0.48, 0.48, 0.50, 0.55, 0.58, 0.60, 0.65, 0.65, 0.65, 0.50, 0.45, 0.36, 0.38, 0.40, 0.55, 0.55, 0.45, 0.40, 0.40, 0.60, 0.60, 0.58, 0.55, 0.50)
|
||||
sixToEleven[14.18] = arrayOf(0.53, 0.53, 0.55, 0.60, 0.65, 0.68, 0.70, 0.70, 0.68, 0.60, 0.55, 0.40, 0.40, 0.45, 0.60, 0.60, 0.50, 0.45, 0.45, 0.63, 0.65, 0.63, 0.60, 0.60)
|
||||
sixToEleven[15.17] = arrayOf(0.55, 0.58, 0.60, 0.65, 0.70, 0.70, 0.75, 0.75, 0.70, 0.65, 0.60, 0.42, 0.42, 0.45, 0.65, 0.65, 0.60, 0.50, 0.50, 0.68, 0.68, 0.65, 0.63, 0.63)
|
||||
sixToEleven[16.50] = arrayOf(0.60, 0.63, 0.65, 0.70, 0.70, 0.70, 0.80, 0.80, 0.80, 0.70, 0.60, 0.45, 0.45, 0.50, 0.65, 0.70, 0.60, 0.55, 0.55, 0.75, 0.75, 0.70, 0.65, 0.65)
|
||||
|
||||
twelveToSeventeen[10.70] = arrayOf(0.30, 0.30, 0.30, 0.30, 0.40, 0.40, 0.60, 0.60, 0.60, 0.40, 0.35, 0.30, 0.30, 0.35, 0.45, 0.50, 0.40, 0.30, 0.30, 0.40, 0.50, 0.40, 0.40, 0.30)
|
||||
twelveToSeventeen[11.10] = arrayOf(0.30, 0.30, 0.30, 0.35, 0.40, 0.45, 0.60, 0.60, 0.60, 0.40, 0.40, 0.30, 0.35, 0.40, 0.50, 0.50, 0.30, 0.30, 0.30, 0.50, 0.50, 0.50, 0.30, 0.30)
|
||||
twelveToSeventeen[11.60] = arrayOf(0.30, 0.30, 0.35, 0.45, 0.45, 0.50, 0.65, 0.65, 0.65, 0.45, 0.40, 0.40, 0.40, 0.40, 0.50, 0.55, 0.55, 0.45, 0.45, 0.50, 0.50, 0.50, 0.40, 0.40)
|
||||
twelveToSeventeen[13.00] = arrayOf(0.40, 0.40, 0.40, 0.50, 0.55, 0.60, 0.70, 0.70, 0.70, 0.60, 0.50, 0.40, 0.40, 0.40, 0.50, 0.60, 0.60, 0.50, 0.50, 0.60, 0.60, 0.60, 0.40, 0.30)
|
||||
twelveToSeventeen[15.60] = arrayOf(0.45, 0.50, 0.50, 0.60, 0.65, 0.70, 0.80, 0.80, 0.80, 0.70, 0.60, 0.60, 0.50, 0.50, 0.60, 0.70, 0.70, 0.60, 0.60, 0.60, 0.70, 0.70, 0.50, 0.50)
|
||||
twelveToSeventeen[17.00] = arrayOf(0.50, 0.55, 0.60, 0.70, 0.75, 0.80, 1.00, 1.00, 1.00, 0.80, 0.70, 0.60, 0.60, 0.60, 0.70, 0.80, 0.80, 0.65, 0.65, 0.65, 0.70, 0.70, 0.60, 0.60)
|
||||
twelveToSeventeen[18.00] = arrayOf(0.60, 0.65, 0.70, 0.80, 0.85, 0.90, 1.10, 1.10, 1.10, 0.90, 0.80, 0.60, 0.60, 0.60, 0.70, 0.80, 0.80, 0.70, 0.65, 0.70, 0.75, 0.70, 0.60, 0.60)
|
||||
twelveToSeventeen[20.20] = arrayOf(0.70, 0.75, 0.80, 0.90, 0.95, 1.00, 1.10, 1.10, 1.10, 0.90, 0.80, 0.70, 0.70, 0.70, 0.80, 0.90, 0.90, 0.75, 0.75, 0.75, 0.80, 0.80, 0.70, 0.70)
|
||||
twelveToSeventeen[21.60] = arrayOf(0.75, 0.80, 0.90, 0.90, 1.00, 1.00, 1.20, 1.20, 1.20, 0.90, 0.80, 0.70, 0.70, 0.70, 0.90, 1.00, 1.00, 0.80, 0.80, 0.80, 0.80, 0.80, 0.70, 0.70)
|
||||
twelveToSeventeen[23.80] = arrayOf(0.75, 0.80, 0.90, 1.00, 1.10, 1.10, 1.20, 1.20, 1.20, 1.00, 0.90, 0.80, 0.80, 0.80, 0.90, 1.10, 1.10, 0.90, 0.90, 0.90, 1.00, 1.00, 0.80, 0.80)
|
||||
twelveToSeventeen[26.10] = arrayOf(0.80, 0.80, 0.90, 1.00, 1.20, 1.20, 1.30, 1.30, 1.30, 1.10, 1.00, 0.90, 0.90, 0.90, 1.00, 1.20, 1.10, 0.90, 0.90, 1.00, 1.00, 1.00, 0.90, 0.90)
|
||||
twelveToSeventeen[28.00] = arrayOf(0.90, 0.90, 1.00, 1.10, 1.10, 1.20, 1.30, 1.30, 1.30, 1.20, 1.00, 1.00, 1.00, 1.00, 1.20, 1.20, 1.20, 1.00, 1.00, 1.10, 1.10, 1.10, 0.90, 0.90)
|
||||
twelveToSeventeen[30.10] = arrayOf(1.00, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.50, 1.50, 1.30, 1.20, 1.00, 1.00, 1.00, 1.30, 1.40, 1.40, 1.00, 1.00, 1.15, 1.15, 1.10, 1.00, 1.00)
|
||||
twelveToSeventeen[32.60] = arrayOf(1.10, 1.10, 1.20, 1.20, 1.40, 1.50, 1.50, 1.50, 1.50, 1.30, 1.20, 1.10, 1.10, 1.10, 1.40, 1.50, 1.40, 1.10, 1.10, 1.20, 1.20, 1.20, 1.10, 1.10)
|
||||
twelveToSeventeen[35.20] = arrayOf(1.20, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.70, 1.50, 1.40, 1.20, 1.10, 1.10, 1.10, 1.40, 1.50, 1.60, 1.40, 1.20, 1.20, 1.30, 1.30, 1.20, 1.20)
|
||||
twelveToSeventeen[39.00] = arrayOf(1.30, 1.30, 1.40, 1.60, 1.60, 1.60, 1.90, 1.90, 1.90, 1.50, 1.30, 1.20, 1.20, 1.30, 1.50, 1.60, 1.70, 1.80, 1.50, 1.50, 1.60, 1.60, 1.30, 1.30)
|
||||
twelveToSeventeen[42.80] = arrayOf(1.40, 1.40, 1.50, 1.70, 1.80, 1.80, 2.00, 2.00, 2.00, 1.80, 1.80, 1.50, 1.50, 1.50, 1.60, 1.70, 1.80, 1.90, 1.60, 1.60, 1.70, 1.70, 1.50, 1.50)
|
||||
twelveToSeventeen[47.30] = arrayOf(1.50, 1.50, 1.70, 1.70, 2.00, 2.00, 2.20, 2.30, 2.20, 2.00, 1.80, 1.60, 1.60, 1.60, 1.80, 2.00, 2.10, 1.90, 1.80, 1.80, 2.00, 2.00, 1.60, 1.60)
|
||||
}
|
||||
|
||||
private fun closest(map: TreeMap<Double, Array<Double>>, key: Double): Array<Double>? {
|
||||
val low = map.floorEntry(key)
|
||||
val high = map.ceilingEntry(key)
|
||||
var res: Array<Double>? = null
|
||||
if (low != null && high != null) {
|
||||
res = if (Math.abs(key - low.key) < Math.abs(key - high.key))
|
||||
low.value
|
||||
else
|
||||
high.value
|
||||
} else if (low != null || high != null) {
|
||||
res = if (low != null) low.value else high.value
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
fun arrayToJson(b: Array<Double>): JSONArray {
|
||||
val basals = JSONArray()
|
||||
for (i in 0..23) {
|
||||
val time = String.format(Locale.ENGLISH, "%02d:00", i)
|
||||
basals.put(JSONObject().put("time", time).put("value", b[i].toString()))
|
||||
}
|
||||
return basals
|
||||
}
|
||||
|
||||
fun singleValueArray(value: Double, sample: Array<Double>): JSONArray {
|
||||
val array = JSONArray()
|
||||
array.put(JSONObject().put("time", "00:00").put("value", value + sample[0]))
|
||||
array.put(JSONObject().put("time", "06:00").put("value", value + sample[1]))
|
||||
array.put(JSONObject().put("time", "09:00").put("value", value + sample[2]))
|
||||
array.put(JSONObject().put("time", "11:00").put("value", value + sample[3]))
|
||||
array.put(JSONObject().put("time", "14:00").put("value", value + sample[4]))
|
||||
array.put(JSONObject().put("time", "16:00").put("value", value + sample[5]))
|
||||
array.put(JSONObject().put("time", "19:00").put("value", value + sample[6]))
|
||||
return array
|
||||
}
|
||||
}
|
|
@ -1593,14 +1593,23 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
// ---------------- ProfileSwitch handling ---------------
|
||||
|
||||
public List<ProfileSwitch> getProfileSwitchData(boolean ascending) {
|
||||
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);
|
||||
queryBuilder.setCountOf(true);
|
||||
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
|
||||
long count = daoProfileSwitch.countOf(preparedQuery);
|
||||
// now do query of count + 1
|
||||
queryBuilder = daoProfileSwitch.queryBuilder();
|
||||
queryBuilder.orderBy("date", ascending);
|
||||
queryBuilder.limit(count + 1);
|
||||
preparedQuery = queryBuilder.prepare();
|
||||
profileSwitches = daoProfileSwitch.query(preparedQuery);
|
||||
return profileSwitches;
|
||||
} catch (SQLException e) {
|
||||
|
|
|
@ -6,8 +6,11 @@ import com.j256.ormlite.table.DatabaseTable;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
|
||||
/**
|
||||
* Created by mike on 20.09.2017.
|
||||
|
@ -56,4 +59,12 @@ public class TDD {
|
|||
", total=" + total +
|
||||
']';
|
||||
}
|
||||
|
||||
public String toText() {
|
||||
return MainApp.gs(R.string.tddformat, DateUtil.dateStringShort(date), total, bolus, basal);
|
||||
}
|
||||
|
||||
public String toText(int days) {
|
||||
return MainApp.gs(R.string.tddformat, String.format("%d ", days) + MainApp.gs(R.string.days), total, bolus, basal);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,11 +103,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
initializeTempBasalData();
|
||||
initializeTreatmentData();
|
||||
initializeExtendedBolusData();
|
||||
initializeTempTargetData();
|
||||
initializeProfileSwitchData();
|
||||
initializeData(range());
|
||||
super.onStart();
|
||||
disposable.add(RxBus.INSTANCE
|
||||
.toObservable(EventReloadTreatmentData.class)
|
||||
|
@ -115,8 +111,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
.subscribe(event -> {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("EventReloadTreatmentData");
|
||||
initializeTreatmentData();
|
||||
initializeExtendedBolusData();
|
||||
initializeTreatmentData(range());
|
||||
initializeExtendedBolusData(range());
|
||||
updateTotalIOBTreatments();
|
||||
RxBus.INSTANCE.send(event.getNext());
|
||||
},
|
||||
|
@ -125,13 +121,13 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
disposable.add(RxBus.INSTANCE
|
||||
.toObservable(EventReloadProfileSwitchData.class)
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(event -> initializeProfileSwitchData(),
|
||||
.subscribe(event -> initializeProfileSwitchData(range()),
|
||||
FabricPrivacy::logException
|
||||
));
|
||||
disposable.add(RxBus.INSTANCE
|
||||
.toObservable(EventTempTargetChange.class)
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(event -> initializeTempTargetData(),
|
||||
.subscribe(event -> initializeTempTargetData(range()),
|
||||
FabricPrivacy::logException
|
||||
));
|
||||
disposable.add(RxBus.INSTANCE
|
||||
|
@ -140,7 +136,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
.subscribe(event -> {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("EventReloadTempBasalData");
|
||||
initializeTempBasalData();
|
||||
initializeTempBasalData(range());
|
||||
updateTotalIOBTempBasals();
|
||||
},
|
||||
FabricPrivacy::logException
|
||||
|
@ -157,61 +153,61 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
return this.service;
|
||||
}
|
||||
|
||||
private void initializeTreatmentData() {
|
||||
private long range() {
|
||||
double dia = Constants.defaultDIA;
|
||||
if (ConfigBuilderPlugin.getPlugin() != null && ProfileFunctions.getInstance().getProfile() != null)
|
||||
dia = ProfileFunctions.getInstance().getProfile().getDia();
|
||||
return (long) (60 * 60 * 1000L * (24 + dia));
|
||||
}
|
||||
|
||||
public void initializeData(long range) {
|
||||
initializeTempBasalData(range);
|
||||
initializeTreatmentData(range);
|
||||
initializeExtendedBolusData(range);
|
||||
initializeTempTargetData(range);
|
||||
initializeProfileSwitchData(range);
|
||||
}
|
||||
|
||||
private void initializeTreatmentData(long range) {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("initializeTreatmentData");
|
||||
double dia = Constants.defaultDIA;
|
||||
if (ConfigBuilderPlugin.getPlugin() != null && ProfileFunctions.getInstance().getProfile() != null)
|
||||
dia = ProfileFunctions.getInstance().getProfile().getDia();
|
||||
long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
|
||||
synchronized (treatments) {
|
||||
treatments.clear();
|
||||
treatments.addAll(getService().getTreatmentDataFromTime(fromMills, false));
|
||||
treatments.addAll(getService().getTreatmentDataFromTime(DateUtil.now() - range, false));
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeTempBasalData() {
|
||||
private void initializeTempBasalData(long range) {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("initializeTempBasalData");
|
||||
double dia = Constants.defaultDIA;
|
||||
if (ConfigBuilderPlugin.getPlugin() != null && ProfileFunctions.getInstance().getProfile() != null)
|
||||
dia = ProfileFunctions.getInstance().getProfile().getDia();
|
||||
long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
|
||||
|
||||
synchronized (tempBasals) {
|
||||
tempBasals.reset().add(MainApp.getDbHelper().getTemporaryBasalsDataFromTime(fromMills, false));
|
||||
tempBasals.reset().add(MainApp.getDbHelper().getTemporaryBasalsDataFromTime(DateUtil.now() - range, false));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void initializeExtendedBolusData() {
|
||||
private void initializeExtendedBolusData(long range) {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("initializeExtendedBolusData");
|
||||
double dia = Constants.defaultDIA;
|
||||
if (ConfigBuilderPlugin.getPlugin() != null && ProfileFunctions.getInstance().getProfile() != null)
|
||||
dia = ProfileFunctions.getInstance().getProfile().getDia();
|
||||
long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
|
||||
|
||||
synchronized (extendedBoluses) {
|
||||
extendedBoluses.reset().add(MainApp.getDbHelper().getExtendedBolusDataFromTime(fromMills, false));
|
||||
extendedBoluses.reset().add(MainApp.getDbHelper().getExtendedBolusDataFromTime(DateUtil.now() - range, false));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void initializeTempTargetData() {
|
||||
private void initializeTempTargetData(long range) {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("initializeTempTargetData");
|
||||
synchronized (tempTargets) {
|
||||
long fromMills = System.currentTimeMillis() - 60 * 60 * 1000L * 24;
|
||||
tempTargets.reset().add(MainApp.getDbHelper().getTemptargetsDataFromTime(fromMills, false));
|
||||
tempTargets.reset().add(MainApp.getDbHelper().getTemptargetsDataFromTime(DateUtil.now() - range, false));
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeProfileSwitchData() {
|
||||
private void initializeProfileSwitchData(long range) {
|
||||
if (L.isEnabled(L.DATATREATMENTS))
|
||||
log.debug("initializeProfileSwitchData");
|
||||
synchronized (profiles) {
|
||||
profiles.reset().add(MainApp.getDbHelper().getProfileSwitchData(false));
|
||||
profiles.reset().add(MainApp.getDbHelper().getProfileSwitchData(DateUtil.now() - range, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,7 +257,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
|
||||
if (!pumpInterface.isFakingTempsByExtendedBoluses())
|
||||
synchronized (extendedBoluses) {
|
||||
for (Integer pos = 0; pos < extendedBoluses.size(); pos++) {
|
||||
for (int pos = 0; pos < extendedBoluses.size(); pos++) {
|
||||
ExtendedBolus e = extendedBoluses.get(pos);
|
||||
if (e.date > time) continue;
|
||||
IobTotal calc = e.iobCalc(time);
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
|
@ -14,16 +15,21 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
|||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import kotlinx.android.synthetic.main.close.*
|
||||
import kotlinx.android.synthetic.main.profileviewer_fragment.*
|
||||
import org.json.JSONObject
|
||||
|
||||
class ProfileViewerDialog : DialogFragment() {
|
||||
private var time: Long = 0
|
||||
|
||||
enum class Mode(val i: Int) {
|
||||
RUNNING_PROFILE(1),
|
||||
PUMP_PROFILE(2)
|
||||
PUMP_PROFILE(2),
|
||||
CUSTOM_PROFILE(3)
|
||||
}
|
||||
|
||||
private var mode: Mode = Mode.RUNNING_PROFILE;
|
||||
private var mode: Mode = Mode.RUNNING_PROFILE
|
||||
private var customProfileJson: String = ""
|
||||
private var customProfileName: String = ""
|
||||
private var customProfileUnits: String = Constants.MGDL
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
|
@ -31,6 +37,9 @@ class ProfileViewerDialog : DialogFragment() {
|
|||
(savedInstanceState ?: arguments)?.let { bundle ->
|
||||
time = bundle.getLong("time", 0)
|
||||
mode = Mode.values()[bundle.getInt("mode", Mode.RUNNING_PROFILE.ordinal)]
|
||||
customProfileJson = bundle.getString("customProfile", "")
|
||||
customProfileUnits = bundle.getString("customProfileUnits", Constants.MGDL)
|
||||
customProfileName = bundle.getString("customProfileName", "")
|
||||
}
|
||||
|
||||
return inflater.inflate(R.layout.profileviewer_fragment, container, false)
|
||||
|
@ -64,6 +73,13 @@ class ProfileViewerDialog : DialogFragment() {
|
|||
profileview_reload.visibility = View.VISIBLE
|
||||
profileview_datelayout.visibility = View.GONE
|
||||
}
|
||||
Mode.CUSTOM_PROFILE -> {
|
||||
profile = Profile(JSONObject(customProfileJson), customProfileUnits)
|
||||
profileName = customProfileName
|
||||
date = ""
|
||||
profileview_reload.visibility = View.GONE
|
||||
profileview_datelayout.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
profileview_noprofile.visibility = View.VISIBLE
|
||||
|
||||
|
@ -92,6 +108,9 @@ class ProfileViewerDialog : DialogFragment() {
|
|||
super.onSaveInstanceState(bundle)
|
||||
bundle.putLong("time", time)
|
||||
bundle.putInt("mode", mode.ordinal)
|
||||
bundle.putString("customProfile", customProfileJson)
|
||||
bundle.putString("customProfileName", customProfileName)
|
||||
bundle.putString("customProfileUnits", customProfileUnits)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class TreatmentsProfileSwitchFragment : Fragment() {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
profileswitch_recyclerview.setHasFixedSize(true)
|
||||
profileswitch_recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
profileswitch_recyclerview.adapter = RecyclerProfileViewAdapter(MainApp.getDbHelper().getProfileSwitchData(false))
|
||||
profileswitch_recyclerview.adapter = RecyclerProfileViewAdapter(MainApp.getDbHelper().getProfileSwitchData(DateUtil.now() - T.days(30).msecs(),false))
|
||||
|
||||
profileswitch_refreshfromnightscout.setOnClickListener {
|
||||
val builder = AlertDialog.Builder(this.context!!)
|
||||
|
@ -77,7 +77,7 @@ class TreatmentsProfileSwitchFragment : Fragment() {
|
|||
}
|
||||
|
||||
fun updateGUI() =
|
||||
profileswitch_recyclerview?.swapAdapter(RecyclerProfileViewAdapter(MainApp.getDbHelper().getProfileSwitchData(false)), false)
|
||||
profileswitch_recyclerview?.swapAdapter(RecyclerProfileViewAdapter(MainApp.getDbHelper().getProfileSwitchData(DateUtil.now() - T.days(30).msecs(),false)), false)
|
||||
|
||||
inner class RecyclerProfileViewAdapter(var profileSwitchList: List<ProfileSwitch>) : RecyclerView.Adapter<ProfileSwitchViewHolder>() {
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ProfileSwitchViewHolder {
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
package info.nightscout.androidaps.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.os.Bundle
|
||||
import android.text.Spanned
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.L
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
object ActivityMonitor : Application.ActivityLifecycleCallbacks {
|
||||
private val log = LoggerFactory.getLogger(L.CORE)
|
||||
override fun onActivityPaused(activity: Activity?) {
|
||||
val name = activity?.javaClass?.simpleName ?: return
|
||||
val resumed = SP.getLong("Monitor_" + name + "_" + "resumed", 0)
|
||||
if (resumed == 0L) {
|
||||
log.debug("onActivityPaused: $name resumed == 0")
|
||||
return
|
||||
}
|
||||
val elapsed = DateUtil.now() - resumed
|
||||
val total = SP.getLong("Monitor_" + name + "_total", 0)
|
||||
if (total == 0L) {
|
||||
SP.putLong("Monitor_" + name + "_start", DateUtil.now())
|
||||
}
|
||||
SP.putLong("Monitor_" + name + "_total", total + elapsed)
|
||||
log.debug("onActivityPaused: $name elapsed=$elapsed total=${total + elapsed}")
|
||||
}
|
||||
|
||||
override fun onActivityResumed(activity: Activity?) {
|
||||
val name = activity?.javaClass?.simpleName ?: return
|
||||
log.debug("onActivityResumed: $name")
|
||||
SP.putLong("Monitor_" + name + "_" + "resumed", DateUtil.now())
|
||||
}
|
||||
|
||||
override fun onActivityStarted(activity: Activity?) {
|
||||
}
|
||||
|
||||
override fun onActivityDestroyed(activity: Activity?) {
|
||||
}
|
||||
|
||||
override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
|
||||
}
|
||||
|
||||
override fun onActivityStopped(activity: Activity?) {
|
||||
}
|
||||
|
||||
override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
|
||||
}
|
||||
|
||||
fun toText(): String {
|
||||
val keys: Map<String, *> = SP.getAll()
|
||||
var result = ""
|
||||
for ((key, value) in keys)
|
||||
if (key.startsWith("Monitor") && key.endsWith("total")) {
|
||||
val activity = key.split("_")[1].replace("Activity", "")
|
||||
val duration = DateUtil.niceTimeScalar(value as Long)
|
||||
val start = SP.getLong(key.replace("total", "start"), 0)
|
||||
val days = T.msecs(DateUtil.now() - start).days()
|
||||
result += "<b><span style=\"color:yellow\">$activity:</span></b> <b>$duration</b> in <b>$days</b> days<br>"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun stats() :Spanned {
|
||||
return HtmlHelper.fromHtml("<br><b>" + MainApp.gs(R.string.activitymonitor) + ":</b><br>" + toText())
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
val keys: Map<String, *> = SP.getAll()
|
||||
for ((key, _) in keys)
|
||||
if (key.startsWith("Monitor") && key.endsWith("total")) {
|
||||
SP.remove(key)
|
||||
SP.remove(key.replace("total", "start"))
|
||||
SP.remove(key.replace("total", "resumed"))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -117,6 +117,14 @@ public class DateUtil {
|
|||
return df.format(mills);
|
||||
}
|
||||
|
||||
public static String dateStringShort(long mills) {
|
||||
String format = "MM/dd";
|
||||
if (android.text.format.DateFormat.is24HourFormat(MainApp.instance())) {
|
||||
format = "dd/MM";
|
||||
}
|
||||
return new DateTime(mills).toString(DateTimeFormat.forPattern(format));
|
||||
}
|
||||
|
||||
public static String timeString(Date date) {
|
||||
String format = "hh:mma";
|
||||
if (android.text.format.DateFormat.is24HourFormat(MainApp.instance())) {
|
||||
|
|
|
@ -3,6 +3,8 @@ package info.nightscout.androidaps.utils;
|
|||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
|
||||
/**
|
||||
|
@ -12,6 +14,10 @@ import info.nightscout.androidaps.MainApp;
|
|||
public class SP {
|
||||
private static SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
|
||||
|
||||
static public Map<String, ?> getAll() {
|
||||
return sharedPreferences.getAll();
|
||||
}
|
||||
|
||||
static public void clear() {
|
||||
sharedPreferences.edit().clear().apply();
|
||||
}
|
||||
|
|
26
app/src/main/java/info/nightscout/androidaps/utils/TIR.kt
Normal file
26
app/src/main/java/info/nightscout/androidaps/utils/TIR.kt
Normal file
|
@ -0,0 +1,26 @@
|
|||
package info.nightscout.androidaps.utils
|
||||
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class TIR(val date: Long, val lowThreshold: Double, val highThreshold: Double) {
|
||||
internal var below = 0
|
||||
internal var inRange = 0
|
||||
internal var above = 0
|
||||
internal var error = 0
|
||||
internal var count = 0
|
||||
|
||||
fun error() = run { error++ }
|
||||
fun below() = run { below++; count++ }
|
||||
fun inRange() = run { inRange++; count++ }
|
||||
fun above() = run { above++; count++ }
|
||||
|
||||
fun belowPct() = if (count > 0) (below.toDouble() / count * 100.0).roundToInt() else 0
|
||||
fun inRangePct() = if (count > 0) (inRange.toDouble() / count * 100.0).roundToInt() else 0
|
||||
fun abovePct() = if (count > 0) (above.toDouble() / count * 100.0).roundToInt() else 0
|
||||
|
||||
fun toText(): String = MainApp.gs(R.string.tirformat, DateUtil.dateStringShort(date), belowPct(), inRangePct(), abovePct())
|
||||
|
||||
fun toText(days: Int): String = MainApp.gs(R.string.tirformat, "%02d".format(days) + " " + MainApp.gs(R.string.days), belowPct(), inRangePct(), abovePct())
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package info.nightscout.androidaps.utils
|
||||
|
||||
import android.text.Spanned
|
||||
import android.util.LongSparseArray
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.db.TDD
|
||||
import info.nightscout.androidaps.logging.L
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
object TddCalculator : TreatmentsPlugin() {
|
||||
private val log = LoggerFactory.getLogger(L.DATATREATMENTS)
|
||||
|
||||
fun calculate(days: Long): LongSparseArray<TDD> {
|
||||
val range = T.days(days + 1).msecs()
|
||||
val startTime = MidnightTime.calc(DateUtil.now()) - T.days(days).msecs()
|
||||
val endTime = MidnightTime.calc(DateUtil.now())
|
||||
initializeData(range)
|
||||
|
||||
|
||||
val result = LongSparseArray<TDD>()
|
||||
for (t in treatmentsFromHistory) {
|
||||
if (!t.isValid) continue
|
||||
if (t.date < startTime || t.date > endTime) continue
|
||||
val midnight = MidnightTime.calc(t.date)
|
||||
val tdd = result[midnight] ?: TDD(midnight, 0.0, 0.0, 0.0)
|
||||
tdd.bolus += t.insulin
|
||||
result.put(midnight, tdd)
|
||||
}
|
||||
|
||||
for (t in startTime until endTime step T.mins(5).msecs()) {
|
||||
val midnight = MidnightTime.calc(t)
|
||||
val tdd = result[midnight] ?: TDD(midnight, 0.0, 0.0, 0.0)
|
||||
val tbr = getTempBasalFromHistory(t)
|
||||
val profile = ProfileFunctions.getInstance().getProfile(t) ?: continue
|
||||
val absoluteRate = tbr?.tempBasalConvertedToAbsolute(t, profile) ?: profile.getBasal(t)
|
||||
tdd.basal += absoluteRate / 60.0 * 5.0
|
||||
result.put(midnight, tdd)
|
||||
}
|
||||
for (i in 0 until result.size()) {
|
||||
val tdd = result.valueAt(i)
|
||||
tdd.total = tdd.bolus + tdd.basal
|
||||
}
|
||||
log.debug(result.toString())
|
||||
return result
|
||||
}
|
||||
|
||||
fun averageTDD(tdds: LongSparseArray<TDD>): TDD {
|
||||
val totalTdd = TDD()
|
||||
for (i in 0 until tdds.size()) {
|
||||
val tdd = tdds.valueAt(i)
|
||||
totalTdd.basal += tdd.basal
|
||||
totalTdd.bolus += tdd.bolus
|
||||
totalTdd.total += tdd.total
|
||||
}
|
||||
totalTdd.basal /= tdds.size().toDouble()
|
||||
totalTdd.bolus /= tdds.size().toDouble()
|
||||
totalTdd.total /= tdds.size().toDouble()
|
||||
return totalTdd
|
||||
}
|
||||
|
||||
fun stats(): Spanned {
|
||||
val tdds = calculate(7)
|
||||
val averageTdd = averageTDD(tdds)
|
||||
return HtmlHelper.fromHtml(
|
||||
"<b>" + MainApp.gs(R.string.tdd) + ":</b><br>" +
|
||||
toText(tdds) +
|
||||
"<b>" + MainApp.gs(R.string.average) + ":</b><br>" +
|
||||
averageTdd.toText(tdds.size())
|
||||
)
|
||||
}
|
||||
|
||||
fun toText(tdds: LongSparseArray<TDD>): String {
|
||||
var t = ""
|
||||
for (i in 0 until tdds.size()) {
|
||||
t += "${tdds.valueAt(i).toText()}<br>"
|
||||
}
|
||||
return t
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package info.nightscout.androidaps.utils
|
||||
|
||||
import android.text.Spanned
|
||||
import android.util.LongSparseArray
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
|
||||
object TirCalculator {
|
||||
fun calculate(days: Long, lowMgdl: Double, highMgdl: Double): LongSparseArray<TIR> {
|
||||
if (lowMgdl < 39) throw RuntimeException("Low below 39")
|
||||
if (lowMgdl > highMgdl) throw RuntimeException("Low > High")
|
||||
val startTime = MidnightTime.calc(DateUtil.now()) - T.days(days).msecs()
|
||||
val endTime = MidnightTime.calc(DateUtil.now())
|
||||
|
||||
val bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime(startTime, endTime, true)
|
||||
val result = LongSparseArray<TIR>()
|
||||
for (bg in bgReadings) {
|
||||
val midnight = MidnightTime.calc(bg.date)
|
||||
var tir = result[midnight]
|
||||
if (tir == null) {
|
||||
tir = TIR(midnight, lowMgdl, highMgdl)
|
||||
result.append(midnight, tir)
|
||||
}
|
||||
if (bg.value < 39) tir.error()
|
||||
if (bg.value >= 39 && bg.value < lowMgdl) tir.below()
|
||||
if (bg.value in lowMgdl..highMgdl) tir.inRange()
|
||||
if (bg.value > highMgdl) tir.above()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun averageTIR(tirs: LongSparseArray<TIR>): TIR {
|
||||
val totalTir =
|
||||
if (tirs.size() > 0) TIR(tirs.valueAt(0).date, tirs.valueAt(0).lowThreshold, tirs.valueAt(0).highThreshold)
|
||||
else TIR(7, 70.0, 180.0)
|
||||
for (i in 0 until tirs.size()) {
|
||||
val tir = tirs.valueAt(i)
|
||||
totalTir.below += tir.below
|
||||
totalTir.inRange += tir.inRange
|
||||
totalTir.above += tir.above
|
||||
totalTir.error += tir.error
|
||||
totalTir.count += tir.count
|
||||
}
|
||||
return totalTir
|
||||
}
|
||||
|
||||
fun stats(): Spanned {
|
||||
val lowTirMgdl = 3.9 * Constants.MMOLL_TO_MGDL
|
||||
val highTirMgdl = 10.0 * Constants.MMOLL_TO_MGDL
|
||||
val lowTitMgdl = 3.9 * Constants.MMOLL_TO_MGDL
|
||||
val highTitMgdl = 7.8 * Constants.MMOLL_TO_MGDL
|
||||
|
||||
val tir7 = calculate(7, lowTirMgdl, highTirMgdl)
|
||||
val averageTir7 = averageTIR(tir7)
|
||||
val tir30 = calculate(30, lowTirMgdl, highTirMgdl)
|
||||
val averageTir30 = averageTIR(tir30)
|
||||
val tit7 = calculate(7, lowTitMgdl, highTitMgdl)
|
||||
val averageTit7 = averageTIR(tit7)
|
||||
val tit30 = calculate(30, lowTitMgdl, highTitMgdl)
|
||||
val averageTit30 = averageTIR(tit30)
|
||||
return HtmlHelper.fromHtml(
|
||||
"<br><b>" + MainApp.gs(R.string.tir) + ":</b><br>" +
|
||||
toText(tir7) +
|
||||
"<br><b>" + MainApp.gs(R.string.average) + " (" + Profile.toCurrentUnitsString(lowTirMgdl) + "-" + Profile.toCurrentUnitsString(highTirMgdl) + "):</b><br>" +
|
||||
averageTir7.toText(tir7.size()) + "<br>" +
|
||||
averageTir30.toText(tir30.size()) +
|
||||
"<br><b>" + MainApp.gs(R.string.average) + " (" + Profile.toCurrentUnitsString(lowTitMgdl) + "-" + Profile.toCurrentUnitsString(highTitMgdl) + "):</b><br>" +
|
||||
averageTit7.toText(tit7.size()) + "<br>" +
|
||||
averageTit30.toText(tit30.size())
|
||||
)
|
||||
}
|
||||
|
||||
fun toText(tirs: LongSparseArray<TIR>): String {
|
||||
var t = ""
|
||||
for (i in 0 until tirs.size()) {
|
||||
t += "${tirs.valueAt(i).toText()}<br>"
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
}
|
89
app/src/main/res/layout/stats_activity.xml
Normal file
89
app/src/main/res/layout/stats_activity.xml
Normal file
|
@ -0,0 +1,89 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView 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=".activities.SurveyActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:paddingStart="10dp"
|
||||
app:srcCompat="@mipmap/ic_launcher" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/statistics"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display1" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_tdds"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_tir"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_activity"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/done_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:orientation="horizontal"
|
||||
android:background="@android:color/transparent"
|
||||
android:gravity="end|right"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/stats_reset"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
style="@style/mdtp_ActionButton.Text"
|
||||
android:text="@string/reset" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/ok"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
style="@style/mdtp_ActionButton.Text"
|
||||
android:text="@string/mdtp_ok" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
183
app/src/main/res/layout/survey_fragment.xml
Normal file
183
app/src/main/res/layout/survey_fragment.xml
Normal file
|
@ -0,0 +1,183 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".activities.SurveyActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/survey_id_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:labelFor="@+id/survey_id"
|
||||
android:text="@string/id"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/survey_id"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/survey_age_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:labelFor="@+id/survey_age"
|
||||
android:text="@string/age"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/survey_age"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_weight="1"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="number" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/survey_weigth_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:labelFor="@+id/survey_weight"
|
||||
android:text="@string/weight"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/survey_weight"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_weight="1"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="number" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/survey_TDD_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:labelFor="@+id/survey_weight"
|
||||
android:text="@string/tdd_total"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/survey_tdd"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_weight="1"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="number" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:text="@string/mostcommonprofile"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/survey_spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="5dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/survey_tdds"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/survey_tir"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/survey_activity"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/survey_submit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/submit" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/survey_profile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/profile" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/survey_comment"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
|
@ -18,6 +18,15 @@
|
|||
android:id="@+id/nav_setupwizard"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/nav_setupwizard" />
|
||||
<item
|
||||
android:id="@+id/nav_stats"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/statistics" />
|
||||
<!-- <item
|
||||
android:id="@+id/nav_survey"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/nav_survey" />
|
||||
-->
|
||||
<item
|
||||
android:id="@+id/nav_about"
|
||||
app:showAsAction="never"
|
||||
|
|
|
@ -1662,4 +1662,22 @@
|
|||
<string name="high_mark_comment">Higher value of in range area (display only)</string>
|
||||
<string name="reorder_label">Reorder</string>
|
||||
|
||||
<string name="age">Age:</string>
|
||||
<string name="weight">Weight:</string>
|
||||
<string name="id">ID:</string>
|
||||
<string name="submit">Submit</string>
|
||||
<string name="mostcommonprofile">Most common profile:</string>
|
||||
<string name="survey_comment">Note: Only data visible on this screen will be anonymously uploaded. ID is assigned to this installation of AndroidAPS. You can submit data again if your main profile get changed but let it running at least for a week to make result visible in time in range. Your help is appreciated.</string>
|
||||
<string name="nav_survey">Survey</string>
|
||||
<string name="invalidage">Invalid age entry</string>
|
||||
<string name="invalidweight">Invalid weight entry</string>
|
||||
<string name="tddformat"><![CDATA[<b>%1$s:</b> ∑: <b>%2$.2f</b> Bol: <b>%3$.2f</b> Bas: <b>%4$.2f</b>]]></string>
|
||||
<string name="tirformat"><![CDATA[<b>%1$s:</b> Low: <b>%2$02d%%</b> In: <b>%3$02d%%</b> High: <b>%4$02d%%</b>]]></string>
|
||||
<string name="average">Average</string>
|
||||
<string name="tdd">TDD</string>
|
||||
<string name="tir">TIR</string>
|
||||
<string name="activitymonitor">Activity monitor</string>
|
||||
<string name="doyouwantresetstats">Do you want to reset activity stats?</string>
|
||||
<string name="statistics">Statistics</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package info.nightscout.androidaps.data.defaultProfile
|
||||
|
||||
import info.nightscout.androidaps.Constants
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class DefaultProfileTest {
|
||||
|
||||
@Test
|
||||
fun profile() {
|
||||
var p = DefaultProfile().profile(5.0, 5.1 / 0.3, 0.0, Constants.MGDL)
|
||||
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().profile(7.0, 10.0 / 0.4, 0.0, Constants.MGDL)
|
||||
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().profile(12.0, 25.0 / 0.5, 0.0, Constants.MGDL)
|
||||
assertEquals(0.80, p.getBasalTimeFromMidnight(0), 0.001)
|
||||
assertEquals(10.0, p.getIcTimeFromMidnight(0), 0.001)
|
||||
assertEquals(2.2, p.getIsfTimeFromMidnight(0), 0.001)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue