Tidepool cleanup

This commit is contained in:
Milos Kozak 2020-01-03 00:26:59 +01:00
parent c45b434647
commit 89b1dda10b
9 changed files with 61 additions and 55 deletions

View file

@ -1,14 +1,14 @@
package info.nightscout.androidaps.plugins.general.tidepool.comm
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolStatus
import org.slf4j.LoggerFactory
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
internal class TidepoolCallback<T>(private val session: Session, val name: String, val onSuccess: () -> Unit, val onFail: () -> Unit) : Callback<T> {
internal class TidepoolCallback<T>(private val rxBus: RxBusWrapper, private val session: Session, val name: String, val onSuccess: () -> Unit, val onFail: () -> Unit) : Callback<T> {
private val log = LoggerFactory.getLogger(L.TIDEPOOL)
override fun onResponse(call: Call<T>, response: Response<T>) {
@ -20,7 +20,7 @@ internal class TidepoolCallback<T>(private val session: Session, val name: Strin
} else {
val msg = name + " was not successful: " + response.code() + " " + response.message()
if (L.isEnabled(L.TIDEPOOL)) log.debug(msg)
RxBus.INSTANCE.send(EventTidepoolStatus(msg))
rxBus.send(EventTidepoolStatus(msg))
onFail()
}
}
@ -28,7 +28,7 @@ internal class TidepoolCallback<T>(private val session: Session, val name: Strin
override fun onFailure(call: Call<T>, t: Throwable) {
val msg = "$name Failed: $t"
if (L.isEnabled(L.TIDEPOOL)) log.debug(msg)
RxBus.INSTANCE.send(EventTidepoolStatus(msg))
rxBus.send(EventTidepoolStatus(msg))
onFail()
}

View file

@ -9,6 +9,7 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolStatus
import info.nightscout.androidaps.plugins.general.tidepool.messages.AuthReplyMessage
import info.nightscout.androidaps.plugins.general.tidepool.messages.AuthRequestMessage
@ -16,6 +17,7 @@ import info.nightscout.androidaps.plugins.general.tidepool.messages.DatasetReply
import info.nightscout.androidaps.plugins.general.tidepool.messages.OpenDatasetRequestMessage
import info.nightscout.androidaps.plugins.general.tidepool.messages.UploadReplyMessage
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.InstanceId
import info.nightscout.androidaps.utils.OKDialog
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -36,7 +38,8 @@ class TidepoolUploader @Inject constructor(
private val mainApp: MainApp,
private val resourceHelper: ResourceHelper,
private val sp: SP,
private val uploadChunk: UploadChunk
private val uploadChunk: UploadChunk,
private val configBuilderPlugin: ConfigBuilderPlugin
) {
private var wl: PowerManager.WakeLock? = null
@ -80,7 +83,7 @@ class TidepoolUploader @Inject constructor(
private fun createSession(): Session {
val service = getRetrofitInstance()?.create(TidepoolApiService::class.java)
return Session(AuthRequestMessage.getAuthRequestHeader(), SESSION_TOKEN_HEADER, service)
return Session(AuthRequestMessage.getAuthRequestHeader(sp), SESSION_TOKEN_HEADER, service)
}
// TODO: call on preference change
@ -105,7 +108,7 @@ class TidepoolUploader @Inject constructor(
rxBus.send(EventTidepoolStatus(("Connecting")))
val call = session?.service?.getLogin(authHeader)
call?.enqueue(TidepoolCallback<AuthReplyMessage>(session!!, "Login", {
call?.enqueue(TidepoolCallback<AuthReplyMessage>(rxBus, session!!, "Login", {
startSession(session!!, doUpload)
}, {
connectionStatus = ConnectionStatus.FAILED
@ -126,7 +129,7 @@ class TidepoolUploader @Inject constructor(
session.authHeader?.let {
val call = session.service?.getLogin(it)
call?.enqueue(TidepoolCallback<AuthReplyMessage>(session, "Login", {
call?.enqueue(TidepoolCallback<AuthReplyMessage>(rxBus, session, "Login", {
OKDialog.show(rootContext, resourceHelper.gs(R.string.tidepool), "Successfully logged into Tidepool.")
}, {
OKDialog.show(rootContext, resourceHelper.gs(R.string.tidepool), "Failed to log into Tidepool.\nCheck that your user name and password are correct.")
@ -144,11 +147,13 @@ class TidepoolUploader @Inject constructor(
val datasetCall = session.service!!.getOpenDataSets(session.token!!,
session.authReply!!.userid!!, BuildConfig.APPLICATION_ID, 1)
datasetCall.enqueue(TidepoolCallback<List<DatasetReplyMessage>>(session, "Get Open Datasets", {
datasetCall.enqueue(TidepoolCallback<List<DatasetReplyMessage>>(rxBus, session, "Get Open Datasets", {
if (session.datasetReply == null) {
rxBus.send(EventTidepoolStatus(("Creating new dataset")))
val call = session.service.openDataSet(session.token!!, session.authReply!!.userid!!, OpenDatasetRequestMessage().getBody())
call.enqueue(TidepoolCallback<DatasetReplyMessage>(session, "Open New Dataset", {
val call = session.service.openDataSet(session.token!!, session.authReply!!.userid!!,
OpenDatasetRequestMessage((configBuilderPlugin.activePump?.serialNumber()
?: InstanceId.instanceId())).getBody())
call.enqueue(TidepoolCallback<DatasetReplyMessage>(rxBus, session, "Open New Dataset", {
connectionStatus = ConnectionStatus.CONNECTED
rxBus.send(EventTidepoolStatus(("New dataset OK")))
if (doUpload) doUpload()
@ -212,7 +217,7 @@ class TidepoolUploader @Inject constructor(
rxBus.send(EventTidepoolStatus(("Uploading")))
if (session.service != null && session.token != null && session.datasetReply != null) {
val call = session.service.doUpload(session.token!!, session.datasetReply!!.getUploadId()!!, body)
call.enqueue(TidepoolCallback<UploadReplyMessage>(session, "Data Upload", {
call.enqueue(TidepoolCallback<UploadReplyMessage>(rxBus, session, "Data Upload", {
uploadChunk.setLastEnd(session.end)
rxBus.send(EventTidepoolStatus(("Upload completed OK")))
releaseWakeLock()
@ -239,7 +244,7 @@ class TidepoolUploader @Inject constructor(
if (session?.datasetReply?.id != null) {
extendWakeLock(60000)
val call = session!!.service?.deleteDataSet(session!!.token!!, session!!.datasetReply!!.id!!)
call?.enqueue(TidepoolCallback(session!!, "Delete Dataset", {
call?.enqueue(TidepoolCallback(rxBus, session!!, "Delete Dataset", {
connectionStatus = ConnectionStatus.DISCONNECTED
rxBus.send(EventTidepoolStatus(("Dataset removed OK")))
releaseWakeLock()
@ -264,7 +269,7 @@ class TidepoolUploader @Inject constructor(
requireNotNull(userId)
extendWakeLock(60000)
val call = session.service?.deleteAllData(token, userId)
call?.enqueue(TidepoolCallback(session, "Delete all data", {
call?.enqueue(TidepoolCallback(rxBus, session, "Delete all data", {
connectionStatus = ConnectionStatus.DISCONNECTED
rxBus.send(EventTidepoolStatus(("All data removed OK")))
releaseWakeLock()

View file

@ -2,15 +2,21 @@ package info.nightscout.androidaps.plugins.general.tidepool.comm
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Intervals
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.db.TemporaryBasal
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.plugins.general.tidepool.elements.*
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolStatus
import info.nightscout.androidaps.plugins.general.tidepool.utils.GsonInstance
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.InstanceId
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.slf4j.LoggerFactory
@ -24,7 +30,9 @@ class UploadChunk @Inject constructor(
private val sp: SP,
private val rxBus: RxBusWrapper,
private val aapsLogger: AAPSLogger,
private val treatmentsPlugin: TreatmentsPlugin
private val profileFunction: ProfileFunction,
private val treatmentsPlugin: TreatmentsPlugin,
private val configBuilderPlugin: ConfigBuilderPlugin
) {
private val MAX_UPLOAD_SIZE = T.days(7).msecs() // don't change this
@ -134,20 +142,34 @@ class UploadChunk @Inject constructor(
return selection
}
private fun fromTemporaryBasals(tbrList: Intervals<TemporaryBasal>, start: Long, end: Long): List<BasalElement> {
val results = LinkedList<BasalElement>()
for (tbr in tbrList.list) {
if (tbr.date >= start && tbr.date <= end && tbr.durationInMinutes != 0)
results.add(BasalElement(tbr, profileFunction))
}
return results
}
private fun getBasals(start: Long, end: Long): List<BasalElement> {
val tbrs = treatmentsPlugin.temporaryBasalsFromHistory
tbrs.merge()
val selection = BasalElement.fromTemporaryBasals(tbrs, start, end) // TODO do not upload running TBR
val selection = fromTemporaryBasals(tbrs, start, end) // TODO do not upload running TBR
if (selection.isNotEmpty())
rxBus.send(EventTidepoolStatus("${selection.size} TBRs selected for upload"))
return selection
}
fun newInstanceOrNull(ps: ProfileSwitch): ProfileElement? = try {
ProfileElement(ps, configBuilderPlugin.activePump?.serialNumber() ?: InstanceId.instanceId())
} catch (e: Throwable) {
null
}
private fun getProfiles(start: Long, end: Long): List<ProfileElement> {
val pss = MainApp.getDbHelper().getProfileSwitchEventsFromTime(start, end, true)
val selection = LinkedList<ProfileElement>()
for (ps in pss) {
ProfileElement.newInstanceOrNull(ps)?.let { selection.add(it) }
newInstanceOrNull(ps)?.let { selection.add(it) }
}
if (selection.size > 0)
rxBus.send(EventTidepoolStatus("${selection.size} ProfileSwitches selected for upload"))

View file

@ -1,12 +1,11 @@
package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose
import info.nightscout.androidaps.data.Intervals
import info.nightscout.androidaps.db.TemporaryBasal
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import java.util.*
class BasalElement(tbr: TemporaryBasal)
class BasalElement(tbr: TemporaryBasal, private val profileFunction: ProfileFunction)
: BaseElement(tbr.date, UUID.nameUUIDFromBytes(("AAPS-basal" + tbr.date).toByteArray()).toString()) {
internal var timestamp: Long = 0 // not exposed
@ -27,18 +26,7 @@ class BasalElement(tbr: TemporaryBasal)
init {
type = "basal"
timestamp = tbr.date
rate = tbr.tempBasalConvertedToAbsolute(tbr.date, ProfileFunctions.getInstance().getProfile(tbr.date))
rate = tbr.tempBasalConvertedToAbsolute(tbr.date, profileFunction.getProfile(tbr.date))
duration = tbr.end() - tbr.start()
}
companion object {
internal fun fromTemporaryBasals(tbrList: Intervals<TemporaryBasal>, start: Long, end: Long): List<BasalElement> {
val results = LinkedList<BasalElement>()
for (tbr in tbrList.list) {
if (tbr.date >= start && tbr.date <= end && tbr.durationInMinutes != 0)
results.add(BasalElement(tbr))
}
return results
}
}
}

View file

@ -9,7 +9,7 @@ import info.nightscout.androidaps.utils.InstanceId
import java.util.*
import kotlin.collections.ArrayList
class ProfileElement private constructor(ps: ProfileSwitch)
class ProfileElement(ps: ProfileSwitch, serialNumber: String)
: BaseElement(ps.date, UUID.nameUUIDFromBytes(("AAPS-profile" + ps.date).toByteArray()).toString()) {
@Expose
@ -25,11 +25,9 @@ class ProfileElement private constructor(ps: ProfileSwitch)
@Expose
internal var insulinSensitivities: IsfProfile = IsfProfile()
@Expose
internal var deviceId: String = TidepoolUploader.PUMP_TYPE + ":" + (ConfigBuilderPlugin.getPlugin().activePump?.serialNumber()
?: InstanceId.instanceId())
internal var deviceId: String = TidepoolUploader.PUMP_TYPE + ":" + serialNumber
@Expose
internal var deviceSerialNumber: String = ConfigBuilderPlugin.getPlugin().activePump?.serialNumber()
?: InstanceId.instanceId()
internal var deviceSerialNumber: String = serialNumber
@Expose
internal var clockDriftOffset: Long = 0
@Expose
@ -96,16 +94,6 @@ class ProfileElement private constructor(ps: ProfileSwitch)
@field:Expose
internal var amount: Double
)
companion object {
@JvmStatic
fun newInstanceOrNull(ps: ProfileSwitch): ProfileElement? = try {
ProfileElement(ps)
} catch (e: Throwable) {
null
}
}
}

View file

@ -1,17 +1,17 @@
package info.nightscout.androidaps.plugins.general.tidepool.messages
import info.nightscout.androidaps.R
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.StringUtils
import info.nightscout.androidaps.utils.sharedPreferences.SP
import okhttp3.Credentials
class AuthRequestMessage : BaseMessage() {
companion object {
fun getAuthRequestHeader(): String? {
val username = SP.getString(R.string.key_tidepool_username, null)
val password = SP.getString(R.string.key_tidepool_password, null)
fun getAuthRequestHeader(sp: SP): String? {
val username = sp.getStringOrNull(R.string.key_tidepool_username, null)
val password = sp.getStringOrNull(R.string.key_tidepool_password, null)
return if (StringUtils.emptyString(username) || StringUtils.emptyString(password)) null else Credentials.basic(username.trim { it <= ' ' }, password)
return if (StringUtils.emptyString(username) || StringUtils.emptyString(password)) null else Credentials.basic(username!!.trim { it <= ' ' }, password!!)
}
}
}

View file

@ -9,11 +9,10 @@ import info.nightscout.androidaps.utils.InstanceId
import info.nightscout.androidaps.utils.T
import java.util.*
class OpenDatasetRequestMessage : BaseMessage() {
class OpenDatasetRequestMessage (val serialNumber : String): BaseMessage() {
@Expose
var deviceId: String = TidepoolUploader.PUMP_TYPE + ":" + (ConfigBuilderPlugin.getPlugin().activePump?.serialNumber()
?: InstanceId.instanceId())
var deviceId: String = TidepoolUploader.PUMP_TYPE + ":" + serialNumber
@Expose
var time = DateUtil.toISOAsUTC(DateUtil.now())
@Expose

View file

@ -15,6 +15,7 @@ interface SP {
fun remove(@StringRes resourceID: Int)
fun remove(key: String)
fun getString(@StringRes resourceID: Int, defaultValue: String): String
fun getStringOrNull(@StringRes resourceID: Int, defaultValue: String?): String?
fun getString(key: String, defaultValue: String): String
fun getBoolean(@StringRes resourceID: Int, defaultValue: Boolean): Boolean
fun getBoolean(key: String, defaultValue: Boolean): Boolean

View file

@ -31,6 +31,9 @@ class SPImplementation @Inject constructor(
override fun getString(resourceID: Int, defaultValue: String): String =
sharedPreferences.getString(resourceHelper.gs(resourceID), defaultValue) ?: defaultValue
override fun getStringOrNull(resourceID: Int, defaultValue: String?): String? =
sharedPreferences.getString(resourceHelper.gs(resourceID), defaultValue) ?: defaultValue
override fun getString(key: String, defaultValue: String): String =
sharedPreferences.getString(key, defaultValue) ?: defaultValue