code tweaking, upload profile
This commit is contained in:
parent
21a49f731c
commit
ba0b7ec83d
|
@ -400,6 +400,19 @@ public class Profile {
|
|||
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + MainApp.gs(R.string.profile_per_unit));
|
||||
}
|
||||
|
||||
public ProfileValue[] getIsfs() {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(ic);
|
||||
ProfileValue[] ret = new ProfileValue[isf_v.size()];
|
||||
|
||||
for (Integer index = 0; index < isf_v.size(); index++) {
|
||||
Integer tas = (int) isf_v.keyAt(index);
|
||||
double value = isf_v.valueAt(index);
|
||||
ret[index] = new ProfileValue(tas, value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public double getIc() {
|
||||
return getIcTimeFromMidnight(secondsFromMidnight());
|
||||
}
|
||||
|
@ -420,6 +433,19 @@ public class Profile {
|
|||
return getValuesList(ic_v, null, new DecimalFormat("0.0"), MainApp.gs(R.string.profile_carbs_per_unit));
|
||||
}
|
||||
|
||||
public ProfileValue[] getIcs() {
|
||||
if (ic_v == null)
|
||||
ic_v = convertToSparseArray(ic);
|
||||
ProfileValue[] ret = new ProfileValue[ic_v.size()];
|
||||
|
||||
for (Integer index = 0; index < ic_v.size(); index++) {
|
||||
Integer tas = (int) ic_v.keyAt(index);
|
||||
double value = ic_v.valueAt(index);
|
||||
ret[index] = new ProfileValue(tas, value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public double getBasal() {
|
||||
return getBasalTimeFromMidnight(secondsFromMidnight());
|
||||
}
|
||||
|
@ -441,8 +467,8 @@ public class Profile {
|
|||
return getValuesList(basal_v, null, new DecimalFormat("0.00"), MainApp.gs(R.string.profile_ins_units_per_hout));
|
||||
}
|
||||
|
||||
public class BasalValue {
|
||||
public BasalValue(int timeAsSeconds, double value) {
|
||||
public class ProfileValue {
|
||||
public ProfileValue(int timeAsSeconds, double value) {
|
||||
this.timeAsSeconds = timeAsSeconds;
|
||||
this.value = value;
|
||||
}
|
||||
|
@ -451,15 +477,15 @@ public class Profile {
|
|||
public double value;
|
||||
}
|
||||
|
||||
public synchronized BasalValue[] getBasalValues() {
|
||||
public synchronized ProfileValue[] getBasalValues() {
|
||||
if (basal_v == null)
|
||||
basal_v = convertToSparseArray(basal);
|
||||
BasalValue[] ret = new BasalValue[basal_v.size()];
|
||||
ProfileValue[] ret = new ProfileValue[basal_v.size()];
|
||||
|
||||
for (Integer index = 0; index < basal_v.size(); index++) {
|
||||
Integer tas = (int) basal_v.keyAt(index);
|
||||
double value = basal_v.valueAt(index);
|
||||
ret[index] = new BasalValue(tas, value);
|
||||
ret[index] = new ProfileValue(tas, value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -500,6 +526,34 @@ public class Profile {
|
|||
return getValueToTime(targetHigh_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public class TargetValue {
|
||||
public TargetValue(int timeAsSeconds, double low, double high) {
|
||||
this.timeAsSeconds = timeAsSeconds;
|
||||
this.low = low;
|
||||
this.high = high;
|
||||
}
|
||||
|
||||
public int timeAsSeconds;
|
||||
public double low;
|
||||
public double high;
|
||||
}
|
||||
|
||||
public TargetValue[] getTargets() {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
TargetValue[] ret = new TargetValue[targetLow_v.size()];
|
||||
|
||||
for (Integer index = 0; index < targetLow_v.size(); index++) {
|
||||
Integer tas = (int) targetLow_v.keyAt(index);
|
||||
double low = targetLow_v.valueAt(index);
|
||||
double high = targetHigh_v.valueAt(index);
|
||||
ret[index] = new TargetValue(tas, low, high);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String getTargetList() {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
|
|
|
@ -1557,6 +1557,24 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<ProfileSwitch> getProfileSwitchEventsFromTime(long from, long to, boolean ascending) {
|
||||
try {
|
||||
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
|
||||
List<ProfileSwitch> profileSwitches;
|
||||
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
|
||||
queryBuilder.orderBy("date", ascending);
|
||||
queryBuilder.limit(100L);
|
||||
Where where = queryBuilder.where();
|
||||
where.between("date", from, to);
|
||||
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
|
||||
profileSwitches = daoProfileSwitch.query(preparedQuery);
|
||||
return profileSwitches;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public boolean createOrUpdate(ProfileSwitch profileSwitch) {
|
||||
try {
|
||||
ProfileSwitch old;
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package info.nightscout.androidaps.plugins.general.tidepool;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
@ -12,9 +16,12 @@ import info.nightscout.androidaps.plugins.common.SubscriberFragment;
|
|||
import info.nightscout.androidaps.plugins.general.tidepool.comm.TidepoolUploader;
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolDoUpload;
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolResetData;
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolUpdateGUI;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
|
||||
public class TidepoolJavaFragment extends SubscriberFragment {
|
||||
private TextView logTextView;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
@ -34,11 +41,24 @@ public class TidepoolJavaFragment extends SubscriberFragment {
|
|||
resetStart.setOnClickListener(v4 -> {
|
||||
SP.putLong(R.string.key_tidepool_last_end, 0);
|
||||
});
|
||||
|
||||
logTextView = view.findViewById(R.id.tidepool_log);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventTidepoolUpdateGUI ignored) {
|
||||
updateGUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateGUI() {
|
||||
|
||||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(() -> {
|
||||
TidepoolPlugin.INSTANCE.updateLog();
|
||||
logTextView.setText(TidepoolPlugin.INSTANCE.getTextLog());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.general.tidepool
|
|||
|
||||
import android.text.Html
|
||||
import com.squareup.otto.Subscribe
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.events.EventNetworkChange
|
||||
|
@ -10,15 +11,16 @@ import info.nightscout.androidaps.interfaces.PluginBase
|
|||
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.logging.L
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.comm.Session
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.comm.TidepoolUploader
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolDoUpload
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolResetData
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolStatus
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolUpdateGUI
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.utils.RateLimit
|
||||
import info.nightscout.androidaps.receivers.ChargingStateReceiver
|
||||
import info.nightscout.androidaps.utils.SP
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.ToastUtils
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.util.*
|
||||
|
||||
|
@ -33,15 +35,12 @@ object TidepoolPlugin : PluginBase(PluginDescription()
|
|||
private val log = LoggerFactory.getLogger(L.TIDEPOOL)
|
||||
private var wifiConnected = false
|
||||
|
||||
var session: Session? = null
|
||||
|
||||
private val listLog = ArrayList<EventTidepoolStatus>()
|
||||
internal var textLog = Html.fromHtml("")
|
||||
var textLog = Html.fromHtml("")
|
||||
var status = ""
|
||||
|
||||
var paused: Boolean = false
|
||||
internal var autoscroll: Boolean = false
|
||||
|
||||
var status = ""
|
||||
override fun onStart() {
|
||||
MainApp.bus().register(this)
|
||||
super.onStart()
|
||||
|
@ -53,9 +52,10 @@ object TidepoolPlugin : PluginBase(PluginDescription()
|
|||
}
|
||||
|
||||
fun doUpload() {
|
||||
if (session == null)
|
||||
session = TidepoolUploader.doLogin()
|
||||
else TidepoolUploader.doUpload(session!!)
|
||||
if (TidepoolUploader.connectionStatus == TidepoolUploader.ConnectionStatus.DISCONNECTED)
|
||||
TidepoolUploader.doLogin()
|
||||
else
|
||||
TidepoolUploader.doUpload()
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
|
@ -77,13 +77,13 @@ object TidepoolPlugin : PluginBase(PluginDescription()
|
|||
@Suppress("UNUSED_PARAMETER")
|
||||
@Subscribe
|
||||
fun onEventTidepoolResetData(ev: EventTidepoolResetData) {
|
||||
if (session == null)
|
||||
session = TidepoolUploader.doLogin()
|
||||
if (session != null) {
|
||||
TidepoolUploader.deleteDataSet(session!!)
|
||||
SP.putLong(R.string.key_tidepool_last_end, 0)
|
||||
TidepoolUploader.doLogin()
|
||||
if (TidepoolUploader.connectionStatus != TidepoolUploader.ConnectionStatus.CONNECTED) {
|
||||
log.debug("Not connected for deleteDataset")
|
||||
return
|
||||
}
|
||||
TidepoolUploader.deleteDataSet()
|
||||
SP.putLong(R.string.key_tidepool_last_end, 0)
|
||||
TidepoolUploader.doLogin()
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
@ -95,4 +95,36 @@ object TidepoolPlugin : PluginBase(PluginDescription()
|
|||
return isEnabled(PluginType.GENERAL) && SP.getBoolean(R.string.key_cloud_storage_tidepool_enable, false)
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
fun onStatusEvent(ev: EventTidepoolStatus) {
|
||||
addToLog(ev)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun addToLog(ev: EventTidepoolStatus) {
|
||||
synchronized(listLog) {
|
||||
listLog.add(ev)
|
||||
// remove the first line if log is too large
|
||||
if (listLog.size >= Constants.MAX_LOG_LINES) {
|
||||
listLog.removeAt(0)
|
||||
}
|
||||
}
|
||||
MainApp.bus().post(EventTidepoolUpdateGUI())
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun updateLog() {
|
||||
try {
|
||||
val newTextLog = StringBuilder()
|
||||
synchronized(listLog) {
|
||||
for (log in listLog) {
|
||||
newTextLog.append(log.toPreparedHtml())
|
||||
}
|
||||
}
|
||||
textLog = Html.fromHtml(newTextLog.toString())
|
||||
} catch (e: OutOfMemoryError) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, "Out of memory!\nStop using this phone !!!", R.raw.error)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -31,6 +31,14 @@ object TidepoolUploader {
|
|||
|
||||
private var retrofit: Retrofit? = null
|
||||
|
||||
var session: Session? = null
|
||||
|
||||
enum class ConnectionStatus {
|
||||
DISCONNECTED, CONNECTING, CONNECTED, FAILED
|
||||
}
|
||||
|
||||
var connectionStatus: ConnectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED
|
||||
|
||||
fun getRetrofitInstance(): Retrofit? {
|
||||
if (retrofit == null) {
|
||||
|
||||
|
@ -59,25 +67,38 @@ object TidepoolUploader {
|
|||
}
|
||||
|
||||
@Synchronized
|
||||
fun doLogin(): Session? {
|
||||
fun doLogin() {
|
||||
if (!SP.getBoolean(R.string.key_cloud_storage_tidepool_enable, false)) {
|
||||
log.debug("Cannot login as disabled by preference")
|
||||
return null
|
||||
if (L.isEnabled(L.TIDEPOOL))
|
||||
log.debug("Cannot login as disabled by preference")
|
||||
return
|
||||
}
|
||||
if (connectionStatus == TidepoolUploader.ConnectionStatus.CONNECTED || connectionStatus == TidepoolUploader.ConnectionStatus.CONNECTING) {
|
||||
if (L.isEnabled(L.TIDEPOOL))
|
||||
log.debug("Already connected")
|
||||
return
|
||||
}
|
||||
// TODO failure backoff
|
||||
extendWakeLock(30000)
|
||||
val session = Session(AuthRequestMessage.getAuthRequestHeader(), SESSION_TOKEN_HEADER)
|
||||
if (session.authHeader != null) {
|
||||
val call = session.service?.getLogin(session.authHeader!!)
|
||||
session = Session(AuthRequestMessage.getAuthRequestHeader(), SESSION_TOKEN_HEADER)
|
||||
if (session?.authHeader != null) {
|
||||
connectionStatus = TidepoolUploader.ConnectionStatus.CONNECTING
|
||||
status("Connecting")
|
||||
val call = session!!.service?.getLogin(session?.authHeader!!)
|
||||
|
||||
call?.enqueue(TidepoolCallback<AuthReplyMessage>(session, "Login", { startSession(session) }, { loginFailed() }))
|
||||
return session
|
||||
call?.enqueue(TidepoolCallback<AuthReplyMessage>(session!!, "Login", {
|
||||
startSession(session!!)
|
||||
}, {
|
||||
connectionStatus = TidepoolUploader.ConnectionStatus.FAILED;
|
||||
loginFailed()
|
||||
}))
|
||||
return
|
||||
} else {
|
||||
if (L.isEnabled(L.TIDEPOOL)) log.debug("Cannot do login as user credentials have not been set correctly")
|
||||
connectionStatus = TidepoolUploader.ConnectionStatus.FAILED;
|
||||
status("Invalid credentials")
|
||||
releaseWakeLock()
|
||||
return null
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,48 +135,70 @@ object TidepoolUploader {
|
|||
|
||||
datasetCall.enqueue(TidepoolCallback<List<DatasetReplyMessage>>(session, "Get Open Datasets", {
|
||||
if (session.datasetReply == null) {
|
||||
status("New data set")
|
||||
status("Creating new dataset")
|
||||
val call = session.service.openDataSet(session.token!!, session.authReply!!.userid!!, OpenDatasetRequestMessage().getBody())
|
||||
call.enqueue(TidepoolCallback<DatasetReplyMessage>(session, "Open New Dataset", { doUpload(session) }, { releaseWakeLock() }))
|
||||
call.enqueue(TidepoolCallback<DatasetReplyMessage>(session, "Open New Dataset", {
|
||||
connectionStatus = TidepoolUploader.ConnectionStatus.CONNECTED;
|
||||
status("New dataset OK")
|
||||
releaseWakeLock()
|
||||
}, {
|
||||
status("New dataset FAILED")
|
||||
connectionStatus = TidepoolUploader.ConnectionStatus.FAILED;
|
||||
releaseWakeLock()
|
||||
}))
|
||||
} else {
|
||||
if (L.isEnabled(L.TIDEPOOL)) log.debug("Existing Dataset: " + session.datasetReply!!.getUploadId())
|
||||
if (L.isEnabled(L.TIDEPOOL))
|
||||
log.debug("Existing Dataset: " + session.datasetReply!!.getUploadId())
|
||||
// TODO: Wouldn't need to do this if we could block on the above `call.enqueue`.
|
||||
// ie, do the openDataSet conditionally, and then do `doUpload` either way.
|
||||
status("Appending")
|
||||
doUpload(session)
|
||||
connectionStatus = TidepoolUploader.ConnectionStatus.CONNECTED;
|
||||
status("Appending to existing dataset")
|
||||
releaseWakeLock()
|
||||
}
|
||||
}, { releaseWakeLock() }))
|
||||
}, {
|
||||
connectionStatus = TidepoolUploader.ConnectionStatus.FAILED;
|
||||
status("Open dataset FAILED")
|
||||
releaseWakeLock()
|
||||
}))
|
||||
} else {
|
||||
log.error("Got login response but cannot determine userid - cannot proceed")
|
||||
connectionStatus = TidepoolUploader.ConnectionStatus.FAILED;
|
||||
status("Error userid")
|
||||
releaseWakeLock()
|
||||
}
|
||||
}
|
||||
|
||||
fun doUpload(session: Session) {
|
||||
fun doUpload() {
|
||||
if (!TidepoolPlugin.enabled()) {
|
||||
if (L.isEnabled(L.TIDEPOOL))
|
||||
log.debug("Cannot upload - preference disabled")
|
||||
return
|
||||
}
|
||||
if (session == null) {
|
||||
log.error("Session is null, cannot proceed")
|
||||
return
|
||||
}
|
||||
extendWakeLock(60000)
|
||||
session.iterations++
|
||||
session!!.iterations++
|
||||
val chunk = UploadChunk.getNext(session)
|
||||
if (chunk == null) {
|
||||
log.error("Upload chunk is null, cannot proceed")
|
||||
releaseWakeLock()
|
||||
} else if (chunk.length == 2) {
|
||||
if (L.isEnabled(L.TIDEPOOL)) log.debug("Empty data set - marking as succeeded")
|
||||
doCompletedAndReleaseWakelock()
|
||||
if (L.isEnabled(L.TIDEPOOL)) log.debug("Empty dataset - marking as succeeded")
|
||||
status("No data to upload")
|
||||
releaseWakeLock()
|
||||
} 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()
|
||||
val call = session!!.service!!.doUpload(session!!.token!!, session!!.datasetReply!!.getUploadId()!!, body)
|
||||
call.enqueue(TidepoolCallback<UploadReplyMessage>(session!!, "Data Upload", {
|
||||
UploadChunk.setLastEnd(session!!.end)
|
||||
status("Upload completed OK")
|
||||
releaseWakeLock()
|
||||
}, {
|
||||
status("Upload FAILED")
|
||||
releaseWakeLock()
|
||||
}))
|
||||
}
|
||||
|
@ -168,15 +211,20 @@ object TidepoolUploader {
|
|||
MainApp.bus().post(EventTidepoolStatus(status))
|
||||
}
|
||||
|
||||
private fun doCompletedAndReleaseWakelock() {
|
||||
status("Completed OK")
|
||||
releaseWakeLock()
|
||||
}
|
||||
|
||||
fun deleteDataSet(session: Session) {
|
||||
if (session.datasetReply?.id != null) {
|
||||
val call = session.service?.deleteDataSet(session.token!!, session.datasetReply!!.id!!)
|
||||
call?.enqueue(TidepoolCallback(session, "Delete Dataset", {}, {}))
|
||||
fun deleteDataSet() {
|
||||
if (session?.datasetReply?.id != null) {
|
||||
extendWakeLock(60000)
|
||||
val call = session!!.service?.deleteDataSet(session!!.token!!, session!!.datasetReply!!.id!!)
|
||||
call?.enqueue(TidepoolCallback(session!!, "Delete Dataset", {
|
||||
connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED
|
||||
status("Dataset removed OK")
|
||||
releaseWakeLock()
|
||||
}, {
|
||||
connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED
|
||||
status("Dataset remove FAILED")
|
||||
releaseWakeLock()
|
||||
}))
|
||||
} else {
|
||||
log.error("Got login response but cannot determine dataseId - cannot proceed")
|
||||
}
|
||||
|
|
|
@ -18,7 +18,10 @@ object UploadChunk {
|
|||
|
||||
private val log = LoggerFactory.getLogger(L.TIDEPOOL)
|
||||
|
||||
fun getNext(session: Session): String? {
|
||||
fun getNext(session: Session?): String? {
|
||||
if (session == null)
|
||||
return null
|
||||
|
||||
session.start = getLastEnd()
|
||||
session.end = Math.min(session.start + MAX_UPLOAD_SIZE, DateUtil.now())
|
||||
|
||||
|
@ -48,6 +51,7 @@ object UploadChunk {
|
|||
records.addAll(getBloodTests(start, end))
|
||||
records.addAll(getBasals(start, end))
|
||||
records.addAll(getBgReadings(start, end))
|
||||
records.addAll(getProfiles(start, end))
|
||||
|
||||
return GsonInstance.defaultGsonInstance().toJson(records)
|
||||
}
|
||||
|
@ -116,4 +120,16 @@ object UploadChunk {
|
|||
return BasalElement.fromTemporaryBasals(tbrs)
|
||||
}
|
||||
|
||||
internal fun getProfiles(start: Long, end: Long): List<ProfileElement> {
|
||||
val pss = MainApp.getDbHelper().getProfileSwitchEventsFromTime(start, end, true)
|
||||
if (L.isEnabled(L.TIDEPOOL))
|
||||
log.debug("${pss.size} ProfileSwitches selected for upload")
|
||||
val results = LinkedList<ProfileElement>()
|
||||
for (ps in pss) {
|
||||
val pe = ProfileElement(ps)
|
||||
results.add(pe)
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
}
|
|
@ -19,6 +19,7 @@ class BloodGlucoseElement(careportalEvent: CareportalEvent)
|
|||
var value: Int = 0
|
||||
|
||||
init {
|
||||
type = "cbg"
|
||||
subType = "manual" // TODO
|
||||
var json = if (careportalEvent.json != null) JSONObject(careportalEvent.json) else JSONObject()
|
||||
value = Profile.toMgdl(JsonHelper.safeGetDouble(json, "glucose"), JsonHelper.safeGetString(json, "units", Constants.MGDL)).toInt()
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
package info.nightscout.androidaps.plugins.general.tidepool.elements
|
||||
|
||||
import com.google.gson.annotations.Expose
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.db.ProfileSwitch
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class ProfileElement(ps: ProfileSwitch)
|
||||
: BaseElement(ps.date, UUID.nameUUIDFromBytes(("AAPS-profile" + ps.date).toByteArray()).toString()) {
|
||||
|
||||
@Expose
|
||||
internal var activeSchedule = "Normal"
|
||||
@Expose
|
||||
internal var basalSchedules: BasalProfile = BasalProfile()
|
||||
@Expose
|
||||
internal var units: Units = Units()
|
||||
@Expose
|
||||
internal var bgTargets: TargetProfile = TargetProfile()
|
||||
@Expose
|
||||
internal var carbRatios: IcProfile = IcProfile()
|
||||
@Expose
|
||||
internal var insulinSensitivities: IsfProfile = IsfProfile()
|
||||
|
||||
init {
|
||||
type = "pumpSettings";
|
||||
val profile: Profile = ps.getProfileObject()!!
|
||||
for (br in profile.basalValues)
|
||||
basalSchedules.Normal.add(BasalRate(br.timeAsSeconds * 1000, br.value))
|
||||
for (target in profile.targets)
|
||||
bgTargets.Normal.add(Target(target.timeAsSeconds * 1000, Profile.toMgdl(target.low, profile.units), Profile.toMgdl(target.high, profile.units)))
|
||||
for (ic in profile.ics)
|
||||
carbRatios.Normal.add(Ratio(ic.timeAsSeconds * 1000, ic.value))
|
||||
for (isf in profile.isfs)
|
||||
insulinSensitivities.Normal.add(Ratio(isf.timeAsSeconds * 1000, Profile.toMgdl(isf.value, profile.units)))
|
||||
}
|
||||
|
||||
inner class BasalProfile internal constructor(
|
||||
@field:Expose
|
||||
internal var Normal: ArrayList<BasalRate> = ArrayList() // must be the same var name as activeSchedule
|
||||
)
|
||||
|
||||
inner class BasalRate internal constructor(
|
||||
@field:Expose
|
||||
internal var start: Int,
|
||||
@field:Expose
|
||||
internal var rate: Double
|
||||
)
|
||||
|
||||
inner class Units internal constructor(
|
||||
@field:Expose
|
||||
internal var carb: String = "grams",
|
||||
@field:Expose
|
||||
internal var bg: String = "mg/dL"
|
||||
)
|
||||
|
||||
inner class TargetProfile internal constructor(
|
||||
@field:Expose
|
||||
internal var Normal: ArrayList<Target> = ArrayList() // must be the same var name as activeSchedule
|
||||
)
|
||||
|
||||
inner class Target internal constructor(
|
||||
@field:Expose
|
||||
internal var start: Int,
|
||||
@field:Expose
|
||||
internal var low: Double,
|
||||
@field:Expose
|
||||
internal var high: Double
|
||||
)
|
||||
|
||||
inner class IcProfile internal constructor(
|
||||
@field:Expose
|
||||
internal var Normal: ArrayList<Ratio> = ArrayList() // must be the same var name as activeSchedule
|
||||
)
|
||||
|
||||
inner class IsfProfile internal constructor(
|
||||
@field:Expose
|
||||
internal var Normal: ArrayList<Ratio> = ArrayList() // must be the same var name as activeSchedule
|
||||
)
|
||||
|
||||
inner class Ratio internal constructor(
|
||||
@field:Expose
|
||||
internal var start: Int,
|
||||
@field:Expose
|
||||
internal var amount: Double
|
||||
)
|
||||
|
||||
}
|
|
@ -1,6 +1,22 @@
|
|||
package info.nightscout.androidaps.plugins.general.tidepool.events
|
||||
|
||||
import info.nightscout.androidaps.events.Event
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
class EventTidepoolStatus (val status: String) : Event() {
|
||||
var date : Long = DateUtil.now()
|
||||
|
||||
internal var timeFormat = SimpleDateFormat("HH:mm:ss")
|
||||
|
||||
fun toPreparedHtml(): StringBuilder {
|
||||
val stringBuilder = StringBuilder()
|
||||
stringBuilder.append(timeFormat.format(date))
|
||||
stringBuilder.append(" <b>")
|
||||
stringBuilder.append(status)
|
||||
stringBuilder.append("</b> ")
|
||||
stringBuilder.append("<br>")
|
||||
return stringBuilder
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package info.nightscout.androidaps.plugins.general.tidepool.events;
|
||||
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
|
||||
public class EventTidepoolUpdateGUI extends Event {
|
||||
}
|
|
@ -29,7 +29,7 @@ class OpenDatasetRequestMessage : BaseMessage() {
|
|||
@Expose
|
||||
var deviceManufacturers = arrayOf(((ConfigBuilderPlugin.getPlugin().activeBgSource ?: SourceNSClientPlugin.getPlugin()) as PluginBase).name)
|
||||
@Expose
|
||||
var deviceModel = arrayOf(((ConfigBuilderPlugin.getPlugin().activeBgSource ?: SourceNSClientPlugin.getPlugin()) as PluginBase).name)
|
||||
var deviceModel = ((ConfigBuilderPlugin.getPlugin().activeBgSource ?: SourceNSClientPlugin.getPlugin()) as PluginBase).name
|
||||
@Expose
|
||||
var deviceTags = arrayOf("bgm", "cgm", "insulin-pump")
|
||||
@Expose
|
||||
|
@ -45,7 +45,7 @@ class OpenDatasetRequestMessage : BaseMessage() {
|
|||
@Expose
|
||||
val name = BuildConfig.APPLICATION_ID
|
||||
@Expose
|
||||
val version = "0.1.0" // TODO: const it
|
||||
val version = BuildConfig.VERSION_NAME
|
||||
}
|
||||
|
||||
inner class Deduplicator {
|
||||
|
|
|
@ -417,8 +417,8 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
|
|||
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
|
||||
List<BasalProfileBlock> profileBlocks = new ArrayList<>();
|
||||
for (int i = 0; i < profile.getBasalValues().length; i++) {
|
||||
Profile.BasalValue basalValue = profile.getBasalValues()[i];
|
||||
Profile.BasalValue nextValue = null;
|
||||
Profile.ProfileValue basalValue = profile.getBasalValues()[i];
|
||||
Profile.ProfileValue nextValue = null;
|
||||
if (profile.getBasalValues().length > i + 1)
|
||||
nextValue = profile.getBasalValues()[i + 1];
|
||||
BasalProfileBlock profileBlock = new BasalProfileBlock();
|
||||
|
@ -471,8 +471,8 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
|
|||
if (activeBasalProfile != BasalProfile.PROFILE_1) return false;
|
||||
for (int i = 0; i < profileBlocks.size(); i++) {
|
||||
BasalProfileBlock profileBlock = profileBlocks.get(i);
|
||||
Profile.BasalValue basalValue = profile.getBasalValues()[i];
|
||||
Profile.BasalValue nextValue = null;
|
||||
Profile.ProfileValue basalValue = profile.getBasalValues()[i];
|
||||
Profile.ProfileValue nextValue = null;
|
||||
if (profile.getBasalValues().length > i + 1)
|
||||
nextValue = profile.getBasalValues()[i + 1];
|
||||
if (profileBlock.getDuration() * 60 != (nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds)
|
||||
|
|
|
@ -12,8 +12,6 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
|
@ -388,10 +386,10 @@ public class CommandQueue {
|
|||
}
|
||||
|
||||
// Compare with pump limits
|
||||
Profile.BasalValue[] basalValues = profile.getBasalValues();
|
||||
Profile.ProfileValue[] basalValues = profile.getBasalValues();
|
||||
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
|
||||
|
||||
for (Profile.BasalValue basalValue : basalValues) {
|
||||
for (Profile.ProfileValue basalValue : basalValues) {
|
||||
if (basalValue.value < pump.getPumpDescription().basalMinimumRate) {
|
||||
Notification notification = new Notification(Notification.BASAL_VALUE_BELOW_MINIMUM, MainApp.gs(R.string.basalvaluebelowminimum), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
|
|
Loading…
Reference in a new issue