code cleanup, set uuid properly

This commit is contained in:
Milos Kozak 2019-06-05 16:29:19 +02:00
parent a0c00273bc
commit 21a49f731c
14 changed files with 188 additions and 199 deletions

View file

@ -1387,6 +1387,23 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return new ArrayList<>(); return new ArrayList<>();
} }
public List<CareportalEvent> getCareportalEvents(long start, long end, boolean ascending) {
try {
List<CareportalEvent> careportalEvents;
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.between("date", start, end);
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
preprocessOpenAPSOfflineEvents(careportalEvents);
return careportalEvents;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public void preprocessOpenAPSOfflineEvents(List<CareportalEvent> list) { public void preprocessOpenAPSOfflineEvents(List<CareportalEvent> list) {
OverlappingIntervals offlineEvents = new OverlappingIntervals(); OverlappingIntervals offlineEvents = new OverlappingIntervals();
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {

View file

@ -18,6 +18,7 @@ import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolS
import info.nightscout.androidaps.plugins.general.tidepool.utils.RateLimit import info.nightscout.androidaps.plugins.general.tidepool.utils.RateLimit
import info.nightscout.androidaps.receivers.ChargingStateReceiver import info.nightscout.androidaps.receivers.ChargingStateReceiver
import info.nightscout.androidaps.utils.SP import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.T
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.util.* import java.util.*
@ -63,7 +64,7 @@ object TidepoolPlugin : PluginBase(PluginDescription()
if (enabled() if (enabled()
&& (!SP.getBoolean(R.string.key_tidepool_only_while_charging, false) || ChargingStateReceiver.isCharging()) && (!SP.getBoolean(R.string.key_tidepool_only_while_charging, false) || ChargingStateReceiver.isCharging())
&& (!SP.getBoolean(R.string.key_tidepool_only_while_unmetered, false) || wifiConnected) && (!SP.getBoolean(R.string.key_tidepool_only_while_unmetered, false) || wifiConnected)
&& RateLimit.ratelimit("tidepool-new-data-upload", 1200)) && RateLimit.ratelimit("tidepool-new-data-upload", T.mins(4).secs().toInt()))
doUpload() doUpload()
} }

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.general.tidepool.comm
import info.nightscout.androidaps.logging.L import info.nightscout.androidaps.logging.L
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Response import okhttp3.Response
import okio.Buffer
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.IOException import java.io.IOException
@ -19,7 +20,12 @@ class InfoInterceptor(tag: String) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request() val request = chain.request()
if (request != null && request.body() != null) { if (request != null && request.body() != null) {
if (L.isEnabled(L.TIDEPOOL)) log.debug("Interceptor Body size: " + request.body()!!.contentLength()) if (L.isEnabled(L.TIDEPOOL)) {
log.debug("Interceptor Body size: " + request.body()!!.contentLength())
val requestBuffer = Buffer()
request.body()!!.writeTo(requestBuffer)
log.debug("Interceptor Body: " + requestBuffer.readUtf8())
}
} }
return chain.proceed(request!!) return chain.proceed(request!!)
} }

View file

@ -141,59 +141,38 @@ object TidepoolUploader {
extendWakeLock(60000) extendWakeLock(60000)
session.iterations++ session.iterations++
val chunk = UploadChunk.getNext(session) val chunk = UploadChunk.getNext(session)
if (chunk != null) { if (chunk == null) {
if (chunk.length == 2) {
if (L.isEnabled(L.TIDEPOOL)) log.debug("Empty data set - marking as succeeded")
doCompleted()
} else {
val body = RequestBody.create(MediaType.parse("application/json"), chunk)
val call = session.service!!.doUpload(session.token!!, session.datasetReply!!.getUploadId()!!, body)
status("Uploading")
call.enqueue(TidepoolCallback<UploadReplyMessage>(session, "Data Upload", {
UploadChunk.setLastEnd(session.end)
if (OpenDatasetRequestMessage.isNormal()) {
doClose(session)
} else {
doCompleted()
}
}, { releaseWakeLock() }))
}
} else {
log.error("Upload chunk is null, cannot proceed") log.error("Upload chunk is null, cannot proceed")
releaseWakeLock() releaseWakeLock()
} else if (chunk.length == 2) {
if (L.isEnabled(L.TIDEPOOL)) log.debug("Empty data set - marking as succeeded")
doCompletedAndReleaseWakelock()
} else {
val body = RequestBody.create(MediaType.parse("application/json"), chunk)
val call = session.service!!.doUpload(session.token!!, session.datasetReply!!.getUploadId()!!, body)
status("Uploading")
call.enqueue(TidepoolCallback<UploadReplyMessage>(session, "Data Upload", {
UploadChunk.setLastEnd(session.end)
doCompletedAndReleaseWakelock()
}, {
releaseWakeLock()
}))
} }
} }
private fun status(status: String) { private fun status(status: String) {
log.debug("New status: $status") if (L.isEnabled(L.TIDEPOOL))
log.debug("New status: $status")
MainApp.bus().post(EventTidepoolStatus(status)) MainApp.bus().post(EventTidepoolStatus(status))
} }
private fun doCompleted() { private fun doCompletedAndReleaseWakelock() {
status("Completed OK") status("Completed OK")
if (L.isEnabled(L.TIDEPOOL)) log.debug("ALL COMPLETED OK!")
releaseWakeLock() releaseWakeLock()
} }
private fun doClose(session: Session) {
status("Closing")
extendWakeLock(20000)
val call = session.service!!.closeDataSet(session.token!!, session.datasetReply!!.getUploadId()!!, CloseDatasetRequestMessage().getBody())
call.enqueue(TidepoolCallback(session, "Session Stop", { closeSuccess() }, {}))
}
private fun closeSuccess() {
status("Closed")
if (L.isEnabled(L.TIDEPOOL)) log.debug("Close success")
releaseWakeLock()
}
private fun getDataSet(session: Session) {
val call = session.service!!.getDataSet(session.token!!, "bogus")
call.enqueue(TidepoolCallback(session, "Get Data", {}, {}))
}
fun deleteDataSet(session: Session) { fun deleteDataSet(session: Session) {
if (session.datasetReply?.id != null) { if (session.datasetReply?.id != null) {
val call = session.service?.deleteDataSet(session.token!!, session.datasetReply!!.id!!) val call = session.service?.deleteDataSet(session.token!!, session.datasetReply!!.id!!)

View file

@ -3,10 +3,8 @@ package info.nightscout.androidaps.plugins.general.tidepool.comm
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.logging.L import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.general.tidepool.elements.* import info.nightscout.androidaps.plugins.general.tidepool.elements.*
import info.nightscout.androidaps.plugins.general.tidepool.utils.GsonInstance import info.nightscout.androidaps.plugins.general.tidepool.utils.GsonInstance
import info.nightscout.androidaps.plugins.general.tidepool.utils.LogSlider
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.SP import info.nightscout.androidaps.utils.SP
@ -16,35 +14,32 @@ import java.util.*
object UploadChunk { object UploadChunk {
private val TAG = "TidepoolUploadChunk"
private val MAX_UPLOAD_SIZE = T.days(7).msecs() // don't change this private val MAX_UPLOAD_SIZE = T.days(7).msecs() // don't change this
private val MAX_LATENCY_THRESHOLD_MINUTES: Long = 1440 // minutes per day
private val log = LoggerFactory.getLogger(L.TIDEPOOL) private val log = LoggerFactory.getLogger(L.TIDEPOOL)
fun getNext(session: Session): String? { fun getNext(session: Session): String? {
session.start = getLastEnd() session.start = getLastEnd()
session.end = maxWindow(session.start) session.end = Math.min(session.start + MAX_UPLOAD_SIZE, DateUtil.now())
val result = get(session.start, session.end) val result = get(session.start, session.end)
if (result != null && result.length < 3) { if (result.length < 3) {
if (L.isEnabled(L.TIDEPOOL)) log.debug("No records in this time period, setting start to best end time") if (L.isEnabled(L.TIDEPOOL)) log.debug("No records in this time period, setting start to best end time")
setLastEnd(Math.max(session.end, getOldestRecordTimeStamp())) setLastEnd(Math.max(session.end, getOldestRecordTimeStamp()))
} }
return result return result
} }
operator fun get(start: Long, end: Long): String? { operator fun get(start: Long, end: Long): String {
if (L.isEnabled(L.TIDEPOOL)) log.debug("Syncing data between: " + DateUtil.dateAndTimeFullString(start) + " -> " + DateUtil.dateAndTimeFullString(end)) if (L.isEnabled(L.TIDEPOOL)) log.debug("Syncing data between: " + DateUtil.dateAndTimeFullString(start) + " -> " + DateUtil.dateAndTimeFullString(end))
if (end <= start) { if (end <= start) {
if (L.isEnabled(L.TIDEPOOL)) log.debug("End is <= start: " + DateUtil.dateAndTimeFullString(start) + " " + DateUtil.dateAndTimeFullString(end)) if (L.isEnabled(L.TIDEPOOL)) log.debug("End is <= start: " + DateUtil.dateAndTimeFullString(start) + " " + DateUtil.dateAndTimeFullString(end))
return null return ""
} }
if (end - start > MAX_UPLOAD_SIZE) { if (end - start > MAX_UPLOAD_SIZE) {
if (L.isEnabled(L.TIDEPOOL)) log.debug("More than max range - rejecting") if (L.isEnabled(L.TIDEPOOL)) log.debug("More than max range - rejecting")
return null return ""
} }
val records = LinkedList<BaseElement>() val records = LinkedList<BaseElement>()
@ -57,10 +52,6 @@ object UploadChunk {
return GsonInstance.defaultGsonInstance().toJson(records) return GsonInstance.defaultGsonInstance().toJson(records)
} }
private fun maxWindow(last_end: Long): Long {
return Math.min(last_end + MAX_UPLOAD_SIZE, DateUtil.now())
}
fun getLastEnd(): Long { fun getLastEnd(): Long {
val result = SP.getLong(R.string.key_tidepool_last_end, 0) val result = SP.getLong(R.string.key_tidepool_last_end, 0)
return Math.max(result, DateUtil.now() - T.months(2).msecs()) return Math.max(result, DateUtil.now() - T.months(2).msecs())
@ -75,80 +66,54 @@ object UploadChunk {
} }
} }
// numeric limits must match max time windows
private fun getOldestRecordTimeStamp(): Long {
// TODO we could make sure we include records older than the first bg record for completeness
val start: Long = 0
val end = DateUtil.now()
val bgReadingList = MainApp.getDbHelper().getBgreadingsDataFromTime(start, end, true)
return if (bgReadingList.size > 0)
bgReadingList[0].date
else -1
}
internal fun getTreatments(start: Long, end: Long): List<BaseElement> { internal fun getTreatments(start: Long, end: Long): List<BaseElement> {
val result = LinkedList<BaseElement>() val result = LinkedList<BaseElement>()
val treatments = TreatmentsPlugin.getPlugin().service.getTreatmentDataFromTime(start, end, true) val treatments = TreatmentsPlugin.getPlugin().service.getTreatmentDataFromTime(start, end, true)
for (treatment in treatments) { for (treatment in treatments) {
if (treatment.carbs > 0) { if (treatment.carbs > 0) {
result.add(WizardElement.fromTreatment(treatment)) result.add(WizardElement(treatment))
} else if (treatment.insulin > 0) { } else if (treatment.insulin > 0) {
result.add(BolusElement.fromTreatment(treatment)) result.add(BolusElement(treatment))
} else {
// note only TODO
} }
} }
return result return result
} }
// numeric limits must match max time windows
internal fun getOldestRecordTimeStamp(): Long {
// TODO we could make sure we include records older than the first bg record for completeness
val start: Long = 0
val end = DateUtil.now()
val bgReadingList = MainApp.getDbHelper().getBgreadingsDataFromTime(start, end, false)
return if (bgReadingList.size > 0)
bgReadingList[0].date
else -1
}
@Suppress("UNUSED_PARAMETER")
internal fun getBloodTests(start: Long, end: Long): List<BloodGlucoseElement> { internal fun getBloodTests(start: Long, end: Long): List<BloodGlucoseElement> {
return ArrayList() val readings = MainApp.getDbHelper().getCareportalEvents(start, end, true)
// return BloodGlucoseElement.fromBloodTests(BloodTest.latestForGraph(1800, start, end)); if (L.isEnabled(L.TIDEPOOL))
log.debug("${readings.size} CPs selected for upload")
return BloodGlucoseElement.fromCareportalEvents(readings)
} }
internal fun getBgReadings(start: Long, end: Long): List<SensorGlucoseElement> { internal fun getBgReadings(start: Long, end: Long): List<SensorGlucoseElement> {
val readings = MainApp.getDbHelper().getBgreadingsDataFromTime(start, end, true) val readings = MainApp.getDbHelper().getBgreadingsDataFromTime(start, end, true)
if (L.isEnabled(L.TIDEPOOL)) if (L.isEnabled(L.TIDEPOOL))
log.debug("${readings.size} selected for upload") log.debug("${readings.size} BGs selected for upload")
return SensorGlucoseElement.fromBgReadings(readings) return SensorGlucoseElement.fromBgReadings(readings)
} }
internal fun getBasals(start: Long, end: Long): List<BasalElement> { internal fun getBasals(start: Long, end: Long): List<BasalElement> {
val basals = LinkedList<BasalElement>() val tbrs = MainApp.getDbHelper().getTemporaryBasalsDataFromTime(start, end, true)
val aplist = MainApp.getDbHelper().getTemporaryBasalsDataFromTime(start, end, true) if (L.isEnabled(L.TIDEPOOL))
var current: BasalElement? = null log.debug("${tbrs.size} TBRs selected for upload")
for (temporaryBasal in aplist) { return BasalElement.fromTemporaryBasals(tbrs)
val this_rate = temporaryBasal.tempBasalConvertedToAbsolute(temporaryBasal.date, ProfileFunctions.getInstance().getProfile(temporaryBasal.date))
if (current != null) {
if (this_rate != current.rate) {
current.duration = temporaryBasal.date - current.timestamp
if (L.isEnabled(L.TIDEPOOL)) log.debug("Adding current: " + current.toS())
if (current.isValid()) {
basals.add(current)
} else {
if (L.isEnabled(L.TIDEPOOL)) log.debug("Current basal is invalid: " + current.toS())
}
current = null
} else {
if (L.isEnabled(L.TIDEPOOL)) log.debug("Same rate as previous basal record: " + current.rate + " " + temporaryBasal.toStringFull())
}
}
if (current == null) {
current = BasalElement().create(this_rate, temporaryBasal.date, 0, UUID.nameUUIDFromBytes(("tidepool-basal" + temporaryBasal.date).toByteArray()).toString()) // start duration is 0
}
}
return basals
}
private fun getLatencySliderValue(position: Int): Int {
return LogSlider.calc(0, 300, 15.0, MAX_LATENCY_THRESHOLD_MINUTES.toDouble(), position).toInt()
} }
} }

View file

@ -1,9 +1,12 @@
package info.nightscout.androidaps.plugins.general.tidepool.elements package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose import com.google.gson.annotations.Expose
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.db.TemporaryBasal
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import java.util.*
class BasalElement : BaseElement() { class BasalElement(tbr: TemporaryBasal)
: BaseElement(tbr.date, UUID.nameUUIDFromBytes(("AAPS-basal" + tbr.date).toByteArray()).toString()) {
internal var timestamp: Long = 0 // not exposed internal var timestamp: Long = 0 // not exposed
@ -22,21 +25,18 @@ class BasalElement : BaseElement() {
init { init {
type = "basal"; type = "basal";
timestamp = tbr.date
rate = tbr.tempBasalConvertedToAbsolute(tbr.date, ProfileFunctions.getInstance().getProfile(tbr.date))
duration = duration
} }
fun create(rate: Double, timeStart: Long, duration: Long, uuid: String) : BasalElement { companion object {
this.timestamp = timeStart internal fun fromTemporaryBasals(tbrList: List<TemporaryBasal>): List<BasalElement> {
this.rate = rate val results = LinkedList<BasalElement>()
this.duration = duration for (tbr in tbrList) {
populate(timeStart, uuid) results.add(BasalElement(tbr))
return this }
} return results
}
internal fun isValid(): Boolean {
return rate > -1 && duration > 0
}
internal fun toS(): String {
return rate.toString() + " Start: " + DateUtil.dateAndTimeFullString(timestamp) + " for: " + DateUtil.niceTimeScalar(duration)
} }
} }

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose import com.google.gson.annotations.Expose
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
open class BaseElement { open class BaseElement(timestamp: Long, uuid: String) {
@Expose @Expose
var deviceTime: String = "" var deviceTime: String = ""
@Expose @Expose
@ -15,16 +15,13 @@ open class BaseElement {
@Expose @Expose
var origin: Origin? = null var origin: Origin? = null
init {
internal fun populate(timestamp: Long, uuid: String): BaseElement {
deviceTime = DateUtil.toISONoZone(timestamp) deviceTime = DateUtil.toISONoZone(timestamp)
time = DateUtil.toISOAsUTC(timestamp) time = DateUtil.toISOAsUTC(timestamp)
timezoneOffset = DateUtil.getTimeZoneOffsetMinutes(timestamp) // TODO timezoneOffset = DateUtil.getTimeZoneOffsetMinutes(timestamp) // TODO
origin = Origin(uuid) origin = Origin(uuid)
return this
} }
inner class Origin internal constructor(@field:Expose inner class Origin internal constructor(@field:Expose
internal var id: String) internal var id: String)
} }

View file

@ -1,8 +1,15 @@
package info.nightscout.androidaps.plugins.general.tidepool.elements package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose import com.google.gson.annotations.Expose
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
import java.util.*
class BloodGlucoseElement : BaseElement() { class BloodGlucoseElement(careportalEvent: CareportalEvent)
: BaseElement(careportalEvent.date, UUID.nameUUIDFromBytes(("AAPS-bg" + careportalEvent.date).toByteArray()).toString()) {
@Expose @Expose
var subType: String = "manual" var subType: String = "manual"
@ -11,23 +18,24 @@ class BloodGlucoseElement : BaseElement() {
@Expose @Expose
var value: Int = 0 var value: Int = 0
/* TODO: from careportal ???? init {
fun fromBloodTest(bloodtest: BloodTest): BloodGlucoseElement { subType = "manual" // TODO
val bg = BloodGlucoseElement() var json = if (careportalEvent.json != null) JSONObject(careportalEvent.json) else JSONObject()
bg.populate(bloodtest.timestamp, bloodtest.uuid) value = Profile.toMgdl(JsonHelper.safeGetDouble(json, "glucose"), JsonHelper.safeGetString(json, "units", Constants.MGDL)).toInt()
bg.subType = "manual" // TODO
bg.value = bloodtest.mgdl.toInt()
return bg
} }
fun fromBloodTests(bloodTestList: List<BloodTest>?): List<BloodGlucoseElement>? { companion object {
if (bloodTestList == null) return null
val results = LinkedList<BloodGlucoseElement>() fun fromCareportalEvents(careportalList: List<CareportalEvent>): List<BloodGlucoseElement> {
for (bt in bloodTestList) { val results = LinkedList<BloodGlucoseElement>()
results.add(fromBloodTest(bt)) for (bt in careportalList) {
if (bt.eventType == CareportalEvent.MBG || bt.eventType == CareportalEvent.BGCHECK) {
val bge = BloodGlucoseElement(bt)
if (bge.value > 0)
results.add(BloodGlucoseElement(bt))
}
}
return results
} }
return results
} }
*/
} }

View file

@ -2,8 +2,11 @@ package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose import com.google.gson.annotations.Expose
import info.nightscout.androidaps.plugins.treatments.Treatment import info.nightscout.androidaps.plugins.treatments.Treatment
import java.util.*
class BolusElement(treatment: Treatment)
: BaseElement(treatment.date, UUID.nameUUIDFromBytes(("AAPS-bolus" + treatment.date).toByteArray()).toString()) {
class BolusElement : BaseElement() {
@Expose @Expose
var subType = "normal" var subType = "normal"
@Expose @Expose
@ -13,18 +16,7 @@ class BolusElement : BaseElement() {
init { init {
type = "bolus"; type = "bolus";
} normal = treatment.insulin
expectedNormal = treatment.insulin
fun create(insulinDelivered: Double, timestamp: Long, uuid: String): BolusElement {
this.normal = insulinDelivered
this.expectedNormal = insulinDelivered
populate(timestamp, uuid)
return this
}
companion object {
fun fromTreatment(treatment: Treatment): BolusElement {
return BolusElement().create(treatment.insulin, treatment.date, "uuid-AAPS")
}
} }
} }

View file

@ -4,7 +4,8 @@ import com.google.gson.annotations.Expose
import info.nightscout.androidaps.db.BgReading import info.nightscout.androidaps.db.BgReading
import java.util.* import java.util.*
class SensorGlucoseElement : BaseElement() { class SensorGlucoseElement(bgReading: BgReading)
: BaseElement(bgReading.date, UUID.nameUUIDFromBytes(("AAPS-cgm" + bgReading.date).toByteArray()).toString()) {
@Expose @Expose
internal var units: String = "mg/dL" internal var units: String = "mg/dL"
@ -13,20 +14,14 @@ class SensorGlucoseElement : BaseElement() {
init { init {
this.type = "cbg" this.type = "cbg"
value = bgReading.value.toInt()
} }
companion object { companion object {
internal fun fromBgReading(bgReading: BgReading): SensorGlucoseElement {
val sensorGlucose = SensorGlucoseElement()
sensorGlucose.populate(bgReading.date, "uuid-AAPS")
sensorGlucose.value = bgReading.value.toInt()
return sensorGlucose
}
internal fun fromBgReadings(bgReadingList: List<BgReading>): List<SensorGlucoseElement> { internal fun fromBgReadings(bgReadingList: List<BgReading>): List<SensorGlucoseElement> {
val results = LinkedList<SensorGlucoseElement>() val results = LinkedList<SensorGlucoseElement>()
for (bgReading in bgReadingList) { for (bgReading in bgReadingList) {
results.add(fromBgReading(bgReading)) results.add(SensorGlucoseElement(bgReading))
} }
return results return results
} }

View file

@ -1,10 +1,14 @@
package info.nightscout.androidaps.plugins.general.tidepool.elements package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose import com.google.gson.annotations.Expose
import info.nightscout.androidaps.R2.string.result
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.treatments.Treatment import info.nightscout.androidaps.plugins.treatments.Treatment
import org.json.JSONObject
import java.util.*
class WizardElement internal constructor() : BaseElement() { class WizardElement(treatment: Treatment)
: BaseElement(treatment.date, UUID.nameUUIDFromBytes(("AAPS-wizard" + treatment.date).toByteArray()).toString()) {
@Expose @Expose
var units = "mg/dL" var units = "mg/dL"
@ -17,21 +21,51 @@ class WizardElement internal constructor() : BaseElement() {
init { init {
type = "wizard" type = "wizard"
} carbInput = treatment.carbs
insulinCarbRatio = treatment.ic;
companion object { if (treatment.insulin > 0) {
bolus = BolusElement(treatment)
fun fromTreatment(treatment: Treatment): WizardElement { } else {
val result = WizardElement().populate(treatment.date, "uuid-AAPS") as WizardElement var fake = Treatment()
result.carbInput = treatment.carbs fake.insulin = 0.0001
result.insulinCarbRatio = ProfileFunctions.getInstance().getProfile(treatment.date)!!.ic fake.date = treatment.date;
if (treatment.insulin > 0) { bolus = BolusElement(fake) // fake insulin record
result.bolus = BolusElement().create(treatment.insulin, treatment.date, "uuid-AAPS")
} else {
result.bolus = BolusElement().create(0.0001, treatment.date, "uuid-AAPS") // fake insulin record
}
return result
} }
} }
}
/* TODO fill the rest
{
"type": "wizard",
"bgInput": 16.152676653942503,
"bgTarget": {
"low": 3.6079861941795968,
"high": 6.938434988806917
},
"bolus": "22239d4d592b48ae920b28971cceb48b",
"carbInput": 57,
"insulinCarbRatio": 24,
"insulinOnBoard": 24.265,
"insulinSensitivity": 4.329583433015516,
"recommended": {
"carb": 2.5,
"correction": 2.25,
"net": 0
},
"units": "mmol/L",
"_active": true,
"_groupId": "abcdef",
"_schemaVersion": 0,
"_version": 0,
"clockDriftOffset": 0,
"conversionOffset": 0,
"createdTime": "2018-05-14T08:17:14.353Z",
"deviceId": "DevId0987654321",
"deviceTime": "2018-05-14T18:17:09",
"guid": "18d90ea0-5915-4e95-a8b2-cb22819ce696",
"id": "087c94ccdae84eb5a76b8205a244ec6b",
"time": "2018-05-14T08:17:09.353Z",
"timezoneOffset": 600,
"uploadId": "SampleUploadId"
} }
*/

View file

@ -55,10 +55,6 @@ class OpenDatasetRequestMessage : BaseMessage() {
companion object { companion object {
internal val UPLOAD_TYPE = "continuous" internal val UPLOAD_TYPE = "continuous"
fun isNormal(): Boolean {
return UPLOAD_TYPE == "normal"
}
} }
} }

View file

@ -1,12 +0,0 @@
package info.nightscout.androidaps.plugins.general.tidepool.utils
object LogSlider {
// logarithmic slider with positions start - end representing values start - end, calculate value at selected position
fun calc(sliderStart: Int, sliderEnd: Int, start: Double, end: Double, position: Int): Double {
var valueStart = start
var valueEnd = end
valueStart = Math.log(Math.max(1.0, valueStart))
valueEnd = Math.log(Math.max(1.0, valueEnd))
return Math.exp(valueStart + (valueEnd - valueStart) / (sliderEnd - sliderStart) * (position - sliderStart))
}
}

View file

@ -16,9 +16,11 @@ import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Iob; import info.nightscout.androidaps.data.Iob;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.InsulinInterface;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries; import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
@ -142,6 +144,15 @@ public class Treatment implements DataPointWithLabelInterface {
return null; return null;
} }
public double getIc() {
JSONObject bw = getBoluscalc();
if (bw == null || !bw.has("ic")) {
Profile profile = ProfileFunctions.getInstance().getProfile(date);
return profile.getIc(date);
}
return JsonHelper.safeGetDouble(bw, "ic");
}
/* /*
* mealBolus, _id and isSMB cannot be known coming from pump. Only compare rest * mealBolus, _id and isSMB cannot be known coming from pump. Only compare rest
* TODO: remove debug toasts * TODO: remove debug toasts