Merge pull request #1236 from MilosKozak/RShistory

Rshistory
This commit is contained in:
AdrianLxM 2018-07-21 22:22:11 +02:00 committed by GitHub
commit e3c4de8f7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 224 additions and 102 deletions

View file

@ -1,36 +1,39 @@
<configuration>
<!-- Create a file appender for a log in the application's data directory -->
<property scope="context" name="EXT_FILES_DIR" value="${EXT_DIR:-/sdcard}/Android/data/${PACKAGE_NAME}/files"/>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${EXT_FILES_DIR}/AndroidAPS.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Create a file appender for a log in the application's data directory -->
<property name="EXT_FILES_DIR" scope="context"
value="${EXT_DIR:-/sdcard}/Android/data/${PACKAGE_NAME}/files" />
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${EXT_FILES_DIR}/AndroidAPS.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover. Make sure the path matches the one in the file element or else
the rollover logs are placed in the working directory. -->
<fileNamePattern>${EXT_FILES_DIR}/AndroidAPS._%d{yyyy-MM-dd}_%d{HH-mm-ss, aux}_.%i.zip</fileNamePattern>
<fileNamePattern>${EXT_FILES_DIR}/AndroidAPS._%d{yyyy-MM-dd}_%d{HH-mm-ss, aux}_.%i.zip
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>5MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- keep 30 days' worth of history -->
<maxHistory>120</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level [%class:%line]: %msg%n</pattern>
</encoder>
</appender>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level [%class{0}.%M\(\):%line]: %msg%n</pattern>
</encoder>
</appender>
<appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
<tagEncoder>
<pattern>%logger{0}</pattern>
</tagEncoder>
<encoder>
<pattern>[%thread] %-5level [%class:%line]: %msg%n</pattern>
</encoder>
</appender>
<!-- Write INFO (and higher-level) messages to the log file -->
<root level="DEBUG">
<appender-ref ref="file" />
<appender-ref ref="logcat" />
</root>
<tagEncoder>
<pattern>%logger{0}</pattern>
</tagEncoder>
<encoder>
<pattern>[%thread] [%class{0}.%M\(\):%line]: %msg%n</pattern>
</encoder>
</appender>
<!-- Write INFO (and higher-level) messages to the log file -->
<root level="DEBUG">
<appender-ref ref="file" />
<appender-ref ref="logcat" />
</root>
</configuration>

View file

@ -50,7 +50,7 @@ public interface TreatmentsInterface {
boolean addToHistoryExtendedBolus(ExtendedBolus extendedBolus);
boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo);
boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo, boolean allowUpdate);
TempTarget getTempTargetFromHistory();
TempTarget getTempTargetFromHistory(long time);

View file

@ -70,7 +70,7 @@ public class AutosensData implements DataPointWithLabelInterface {
public double avgDelta = 0d;
public double avgDeviation = 0d;
public double autosensRatio = 1d;
public AutosensResult autosensResult = new AutosensResult();
public double slopeFromMaxDeviation = 0;
public double slopeFromMinDeviation = 999;
public double usedMinCarbsImpact = 0d;
@ -86,7 +86,7 @@ public class AutosensData implements DataPointWithLabelInterface {
@Override
public String toString() {
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation;
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensResult.ratio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation;
}
public int minOld() {

View file

@ -137,6 +137,10 @@ public class IobCobCalculatorPlugin extends PluginBase {
}
void loadBgData(long start) {
if (start < oldestDataAvailable()) {
start = oldestDataAvailable();
log.debug("Limiting BG data to oldest data available: " + DateUtil.dateAndTimeString(start));
}
bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (start - 60 * 60 * 1000L * (24 + dia)), false);
log.debug("BG data loaded. Size: " + bgReadings.size() + " Start date: " + DateUtil.dateAndTimeString(start));
}
@ -388,10 +392,10 @@ public class IobCobCalculatorPlugin extends PluginBase {
time = roundUpTime(previous);
AutosensData data = autosensDataTable.get(time);
if (data != null) {
//log.debug(">>> getAutosensData Cache hit " + data.log(time));
//log.debug(">>> AUTOSENSDATA Cache hit " + data.toString());
return data;
} else {
// log.debug(">>> getAutosensData Cache miss " + new Date(time).toLocaleString());
//log.debug(">>> AUTOSENSDATA Cache miss " + new Date(time).toLocaleString());
return null;
}
}
@ -399,6 +403,14 @@ public class IobCobCalculatorPlugin extends PluginBase {
@Nullable
public AutosensData getLastAutosensDataSynchronized(String reason) {
if (thread != null && thread.isAlive()) {
log.debug("AUTOSENSDATA is waiting for calculation thread: " + reason);
try {
thread.join(5000);
} catch (InterruptedException ignored) {
}
log.debug("AUTOSENSDATA finished waiting for calculation thread: " + reason);
}
synchronized (dataLock) {
return getLastAutosensData(reason);
}
@ -452,6 +464,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
log.debug("AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time));
return null;
} else {
log.debug("AUTOSENSDATA (" + reason + ") " + data.toString());
return data;
}
}
@ -497,14 +510,10 @@ public class IobCobCalculatorPlugin extends PluginBase {
public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) {
synchronized (dataLock) {
return detectSensitivity(fromTime, toTime);
return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(fromTime, toTime);
}
}
static AutosensResult detectSensitivity(long fromTime, long toTime) {
return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(fromTime, toTime);
}
public static JSONArray convertToJSONArray(IobTotal[] iobArray) {
JSONArray array = new JSONArray();
for (int i = 0; i < iobArray.length; i++) {

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.IobCobCalculator;
import android.content.Context;
import android.os.PowerManager;
import android.os.SystemClock;
import android.support.v4.util.LongSparseArray;
import com.crashlytics.android.answers.CustomEvent;
@ -69,6 +70,7 @@ public class IobCobOref1Thread extends Thread {
public final void run() {
mWakeLock.acquire();
try {
log.debug("AUTOSENSDATA thread started: " + from);
if (MainApp.getConfigBuilder() == null) {
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
return; // app still initializing
@ -341,16 +343,19 @@ public class IobCobOref1Thread extends Thread {
AutosensResult sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime);
if (Config.logAutosensData)
log.debug("Sensitivity result: " + sensitivity.toString());
autosensData.autosensRatio = sensitivity.ratio;
autosensData.autosensResult = sensitivity;
if (Config.logAutosensData)
log.debug(autosensData.toString());
}
}
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
log.debug("Finishing calculation thread: " + from);
new Thread(() -> {
SystemClock.sleep(1000);
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
}).start();
} finally {
mWakeLock.release();
MainApp.bus().post(new EventIobCalculationProgress(""));
log.debug("AUTOSENSDATA thread ended: " + from);
}
}

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.IobCobCalculator;
import android.content.Context;
import android.os.PowerManager;
import android.os.SystemClock;
import android.support.v4.util.LongSparseArray;
import com.crashlytics.android.answers.CustomEvent;
@ -68,6 +69,7 @@ public class IobCobThread extends Thread {
public final void run() {
mWakeLock.acquire();
try {
log.debug("AUTOSENSDATA thread started: " + from);
if (MainApp.getConfigBuilder() == null) {
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
return; // app still initializing
@ -268,16 +270,19 @@ public class IobCobThread extends Thread {
AutosensResult sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime);
if (Config.logAutosensData)
log.debug("Sensitivity result: " + sensitivity.toString());
autosensData.autosensRatio = sensitivity.ratio;
autosensData.autosensResult = sensitivity;
if (Config.logAutosensData)
log.debug(autosensData.toString());
}
}
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
log.debug("Finishing calculation thread: " + from);
new Thread(() -> {
SystemClock.sleep(1000);
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
}).start();
} finally {
mWakeLock.release();
MainApp.bus().post(new EventIobCalculationProgress(""));
log.debug("AUTOSENSDATA thread ended: " + from);
}
}

View file

@ -173,7 +173,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
startPart = new Date();
if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) {
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.getPlugin().oldestDataAvailable(), System.currentTimeMillis());
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("OpenAPSPlugin").autosensResult;
} else {
lastAutosensResult = new AutosensResult();
lastAutosensResult.sensResult = "autosens disabled";

View file

@ -180,7 +180,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
startPart = new Date();
if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) {
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.getPlugin().oldestDataAvailable(), System.currentTimeMillis());
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("OpenAPSPlugin").autosensResult;
} else {
lastAutosensResult = new AutosensResult();
lastAutosensResult.sensResult = "autosens disabled";

View file

@ -127,7 +127,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C
startEatingSoonTTCheckbox = view.findViewById(R.id.newcarbs_eating_soon_tt);
startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
startHypoTTCheckbox = view.findViewById(R.id.newcarbs_hypo_tt);
startHypoTTCheckbox.setOnCheckedChangeListener(this);
editTime = view.findViewById(R.id.newcarbs_time);
editTime.setParams(0d, -12 * 60d, 12 * 60d, 5d, new DecimalFormat("0"), false, textWatcher);
@ -160,8 +159,8 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C
if (bgReading != null && bgReading.value < 72) {
startHypoTTCheckbox.setOnCheckedChangeListener(null);
startHypoTTCheckbox.setChecked(true);
startHypoTTCheckbox.setOnClickListener(this);
}
startHypoTTCheckbox.setOnClickListener(this);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
@ -231,13 +230,13 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// Logic to disable a selected radio when pressed. When a checked radio
// is pressed, no CheckChanged event is trigger, so register a Click event
// Logic to disable a selected radio when pressed: when a checked radio
// is pressed, no CheckChanged event is triggered, so register a Click event
// when checking a radio. Since Click events come after CheckChanged events,
// the Click event is triggered immediately after this. Thus, set toggingTT
// the Click event is triggered immediately after this. Thus, set togglingTT
// var to true, so that the first Click event fired after this is ignored.
// Radios remove themselves from Click events once unchecked.
// Since radios are not in a group, manually update their state.
// Since radios are not in a group, their state is manually updated here.
switch (buttonView.getId()) {
case R.id.newcarbs_activity_tt:
togglingTT = true;

View file

@ -286,7 +286,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
detailedBolusInfo.notes = notes;
if (recordOnlyCheckbox.isChecked()) {
detailedBolusInfo.date = time;
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
} else {
detailedBolusInfo.date = now();
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {

View file

@ -25,7 +25,6 @@ import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.Objects;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
@ -187,7 +186,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
}
});
} else {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
}
FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
}

View file

@ -389,7 +389,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
}
});
} else {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
}
FabricPrivacy.getInstance().logCustom(new CustomEvent("Wizard"));
}

View file

@ -879,7 +879,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
});
} else {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
}
FabricPrivacy.getInstance().logCustom(new CustomEvent("QuickWizard"));
}

View file

@ -490,9 +490,9 @@ public class GraphData {
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time);
if (autosensData != null) {
ratioArray.add(new ScaledDataPoint(time, autosensData.autosensRatio - 1, ratioScale));
maxRatioValueFound = Math.max(maxRatioValueFound, autosensData.autosensRatio - 1);
minRatioValueFound = Math.min(minRatioValueFound, autosensData.autosensRatio - 1);
ratioArray.add(new ScaledDataPoint(time, autosensData.autosensResult.ratio - 1, ratioScale));
maxRatioValueFound = Math.max(maxRatioValueFound, autosensData.autosensResult.ratio - 1);
minRatioValueFound = Math.min(minRatioValueFound, autosensData.autosensResult.ratio - 1);
}
}

View file

@ -60,10 +60,7 @@ import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Bolus;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHistory;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHistoryRequest;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Tdd;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.queue.CommandQueue;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.SP;
@ -498,7 +495,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
return deliverBolus(detailedBolusInfo);
} else {
// no bolus required, carb only treatment
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance();
bolusingEvent.t = new Treatment();
@ -689,7 +686,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
dbi.source = Source.PUMP;
dbi.insulin = lastPumpBolus.amount;
try {
boolean treatmentCreated = TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi);
boolean treatmentCreated = TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, false);
if (!treatmentCreated) {
log.error("Adding treatment record overrode an existing record: " + dbi);
if (dbi.isSMB) {
@ -1188,7 +1185,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
dbi.source = Source.PUMP;
dbi.insulin = pumpBolus.amount;
dbi.eventType = CareportalEvent.CORRECTIONBOLUS;
if (TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi)) {
if (TreatmentsPlugin.getPlugin().getService().getPumpRecordById(dbi.pumpId) == null) {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, false);
updated = true;
}
}

View file

@ -199,7 +199,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered);
detailedBolusInfo.insulin = t.insulin;
detailedBolusInfo.date = System.currentTimeMillis();
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
return result;
} else {
PumpEnactResult result = new PumpEnactResult();

View file

@ -202,7 +202,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered);
detailedBolusInfo.insulin = t.insulin;
detailedBolusInfo.date = System.currentTimeMillis();
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
return result;
} else {
PumpEnactResult result = new PumpEnactResult();

View file

@ -133,14 +133,14 @@ public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet {
break;
case DanaRPump.BOLUS:
detailedBolusInfo.insulin = param1 / 100d;
boolean newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
boolean newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
log.debug((newRecord ? "**NEW** " : "") + "EVENT BOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min");
DetailedBolusInfoStorage.remove(detailedBolusInfo.date);
status = "BOLUS " + DateUtil.timeString(datetime);
break;
case DanaRPump.DUALBOLUS:
detailedBolusInfo.insulin = param1 / 100d;
newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
log.debug((newRecord ? "**NEW** " : "") + "EVENT DUALBOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min");
DetailedBolusInfoStorage.remove(detailedBolusInfo.date);
status = "DUALBOLUS " + DateUtil.timeString(datetime);
@ -183,7 +183,7 @@ public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet {
emptyCarbsInfo.date = datetime.getTime();
emptyCarbsInfo.source = Source.PUMP;
emptyCarbsInfo.pumpId = datetime.getTime();
newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(emptyCarbsInfo);
newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(emptyCarbsInfo, false);
log.debug((newRecord ? "**NEW** " : "") + "EVENT CARBS (" + recordCode + ") " + datetime.toLocaleString() + " Carbs: " + param1 + "g");
status = "CARBS " + DateUtil.timeString(datetime);
break;

View file

@ -240,7 +240,7 @@ public class DanaRSService extends Service {
SystemClock.sleep(100);
}
if (DanaRS_Packet_APS_History_Events.lastEventTimeLoaded != 0)
lastHistoryFetched = DanaRS_Packet_APS_History_Events.lastEventTimeLoaded - 45 * 60 * 1000L; // always load last 45 min
lastHistoryFetched = DanaRS_Packet_APS_History_Events.lastEventTimeLoaded - T.mins(1).msecs();
else
lastHistoryFetched = 0;
log.debug("Events loaded");
@ -272,7 +272,7 @@ public class DanaRSService extends Service {
// bleComm.sendMessage(msg);
DanaRS_Packet_APS_Set_Event_History msgSetHistoryEntry_v2 = new DanaRS_Packet_APS_Set_Event_History(DanaRPump.CARBS, carbtime, carbs, 0);
bleComm.sendMessage(msgSetHistoryEntry_v2);
lastHistoryFetched = carbtime - 60000;
lastHistoryFetched = Math.min(lastHistoryFetched, carbtime - T.mins(1).msecs());
}
final long bolusStart = System.currentTimeMillis();

View file

@ -107,14 +107,14 @@ public class MsgHistoryEvents_v2 extends MessageBase {
break;
case DanaRPump.BOLUS:
detailedBolusInfo.insulin = param1 / 100d;
boolean newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
boolean newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
log.debug((newRecord ? "**NEW** " : "") + "EVENT BOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min");
DetailedBolusInfoStorage.remove(detailedBolusInfo.date);
status = "BOLUS " + DateUtil.timeString(datetime);
break;
case DanaRPump.DUALBOLUS:
detailedBolusInfo.insulin = param1 / 100d;
newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
log.debug((newRecord ? "**NEW** " : "") + "EVENT DUALBOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min");
DetailedBolusInfoStorage.remove(detailedBolusInfo.date);
status = "DUALBOLUS " + DateUtil.timeString(datetime);
@ -157,7 +157,7 @@ public class MsgHistoryEvents_v2 extends MessageBase {
emptyCarbsInfo.date = datetime.getTime();
emptyCarbsInfo.source = Source.PUMP;
emptyCarbsInfo.pumpId = datetime.getTime();
newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(emptyCarbsInfo);
newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(emptyCarbsInfo, false);
log.debug((newRecord ? "**NEW** " : "") + "EVENT CARBS (" + recordCode + ") " + datetime.toLocaleString() + " Carbs: " + param1 + "g");
status = "CARBS " + DateUtil.timeString(datetime);
break;

View file

@ -371,7 +371,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
mSerialIOThread.sendMessage(msg);
MsgSetHistoryEntry_v2 msgSetHistoryEntry_v2 = new MsgSetHistoryEntry_v2(DanaRPump.CARBS, carbtime, carbs, 0);
mSerialIOThread.sendMessage(msgSetHistoryEntry_v2);
lastHistoryFetched = carbtime - 60000;
lastHistoryFetched = Math.min(lastHistoryFetched, carbtime - T.mins(1).msecs());
}
final long bolusStart = System.currentTimeMillis();
@ -455,7 +455,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
mSerialIOThread.sendMessage(msg);
MsgSetHistoryEntry_v2 msgSetHistoryEntry_v2 = new MsgSetHistoryEntry_v2(DanaRPump.CARBS, time, amount, 0);
mSerialIOThread.sendMessage(msgSetHistoryEntry_v2);
lastHistoryFetched = time - 1;
lastHistoryFetched = Math.min(lastHistoryFetched, time - T.mins(1).msecs());
return true;
}
@ -485,7 +485,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
}
SystemClock.sleep(200);
if (MsgHistoryEvents_v2.lastEventTimeLoaded != 0)
lastHistoryFetched = MsgHistoryEvents_v2.lastEventTimeLoaded - 45 * 60 * 1000L; //always load last 45 min;
lastHistoryFetched = MsgHistoryEvents_v2.lastEventTimeLoaded - T.mins(1).msecs();
else
lastHistoryFetched = 0;
mDanaRPump.lastConnection = System.currentTimeMillis();

View file

@ -61,7 +61,6 @@ import sugar.free.sightparser.applayer.descriptors.configuration_blocks.BRProfil
import sugar.free.sightparser.applayer.messages.AppLayerMessage;
import sugar.free.sightparser.applayer.messages.remote_control.BolusMessage;
import sugar.free.sightparser.applayer.messages.remote_control.CancelBolusMessage;
import sugar.free.sightparser.applayer.messages.remote_control.CancelTBRMessage;
import sugar.free.sightparser.applayer.messages.remote_control.ExtendedBolusMessage;
import sugar.free.sightparser.applayer.messages.remote_control.StandardBolusMessage;
import sugar.free.sightparser.applayer.messages.status.ActiveBolusesMessage;
@ -456,7 +455,7 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai
bolusingEvent.bolusId = bolusId;
bolusingEvent.percent = 0;
MainApp.bus().post(bolusingEvent);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true);
} else {
log.debug("Failure to deliver treatment");
}

View file

@ -83,6 +83,6 @@ class HistoryLogAdapter {
detailedBolusInfo.source = Source.PUMP;
detailedBolusInfo.pumpId = record_id;
detailedBolusInfo.insulin = insulin;
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true);
}
}

View file

@ -136,7 +136,7 @@ public class MDIPlugin extends PluginBase implements PumpInterface {
result.bolusDelivered = detailedBolusInfo.insulin;
result.carbsDelivered = detailedBolusInfo.carbs;
result.comment = MainApp.gs(R.string.virtualpump_resultok);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
return result;
}

View file

@ -226,7 +226,7 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface {
log.debug("Delivering treatment insulin: " + detailedBolusInfo.insulin + "U carbs: " + detailedBolusInfo.carbs + "g " + result);
MainApp.bus().post(new EventVirtualPumpUpdateGui());
lastDataTime = new Date();
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
return result;
}

View file

@ -50,7 +50,7 @@ public class CarbsGenerator {
}
});
} else {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(carbInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(carbInfo, false);
}
}
}

View file

@ -132,6 +132,24 @@ public class Treatment implements DataPointWithLabelInterface {
return true;
}
/*
* mealBolus, _id and isSMB cannot be known coming from pump. Only compare rest
* TODO: remove debug toasts
*/
public boolean equalsRePumpHistory(Treatment other) {
if (date != other.date) {
return false;
}
if (insulin != other.insulin) {
return false;
}
if (carbs != other.carbs) {
return false;
}
return true;
}
public void copyFrom(Treatment t) {
date = t.date;
_id = t._id;
@ -142,6 +160,14 @@ public class Treatment implements DataPointWithLabelInterface {
isSMB = t.isSMB;
}
public void copyBasics(Treatment t) {
date = t.date;
insulin = t.insulin;
carbs = t.carbs;
pumpId = t.pumpId;
source = t.source;
}
// ----------------- DataPointInterface --------------------
@Override
public double getX() {

View file

@ -241,28 +241,51 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
}
// return true if new record is created
public boolean createOrUpdate(Treatment treatment) {
public UpdateReturn createOrUpdate(Treatment treatment) {
try {
Treatment old;
treatment.date = DatabaseHelper.roundDateToSec(treatment.date);
if (treatment.source == Source.PUMP) {
// check for changed from pump change in NS
QueryBuilder<Treatment, Long> queryBuilder = getDao().queryBuilder();
Where where = queryBuilder.where();
where.eq("pumpId", treatment.pumpId);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
List<Treatment> trList = getDao().query(preparedQuery);
if (trList.size() > 0) {
// do nothing, pump history record cannot be changed
log.debug("TREATMENT: Pump record already found in database: " + treatment.toString());
return false;
Treatment existingTreatment = getPumpRecordById(treatment.pumpId);
if (existingTreatment != null) {
boolean equalRePumpHistory = existingTreatment.equalsRePumpHistory(treatment);
boolean sameSource = existingTreatment.source == treatment.source;
if(!equalRePumpHistory) {
// another treatment exists. Update it with the treatment coming from the pump
log.debug("TREATMENT: Pump record already found in database: " + existingTreatment.toString() + " wanting to add " + treatment.toString());
long oldDate = existingTreatment.date;
getDao().delete(existingTreatment); // need to delete/create because date may change too
existingTreatment.copyBasics(treatment);
getDao().create(existingTreatment);
DatabaseHelper.updateEarliestDataChange(oldDate);
DatabaseHelper.updateEarliestDataChange(existingTreatment.date);
scheduleTreatmentChange(treatment);
return new UpdateReturn(sameSource, false); //updating a pump treatment with another one from the pump is not counted as clash
}
return new UpdateReturn(equalRePumpHistory, false);
}
existingTreatment = getDao().queryForId(treatment.date);
if (existingTreatment != null) {
// another treatment exists with different pumpID. Update it with the treatment coming from the pump
boolean equalRePumpHistory = existingTreatment.equalsRePumpHistory(treatment);
boolean sameSource = existingTreatment.source == treatment.source;
long oldDate = existingTreatment.date;
log.debug("TREATMENT: Pump record already found in database: " + existingTreatment.toString() + " wanting to add " + treatment.toString());
getDao().delete(existingTreatment); // need to delete/create because date may change too
existingTreatment.copyFrom(treatment);
getDao().create(existingTreatment);
DatabaseHelper.updateEarliestDataChange(oldDate);
DatabaseHelper.updateEarliestDataChange(existingTreatment.date);
scheduleTreatmentChange(treatment);
return new UpdateReturn(equalRePumpHistory || sameSource, false);
}
getDao().create(treatment);
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
DatabaseHelper.updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
return true;
return new UpdateReturn(true, true);
}
if (treatment.source == Source.NIGHTSCOUT) {
old = getDao().queryForId(treatment.date);
@ -279,9 +302,9 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
DatabaseHelper.updateEarliestDataChange(old.date);
}
scheduleTreatmentChange(treatment);
return true;
return new UpdateReturn(true, true);
}
return false;
return new UpdateReturn(true, false);
}
// find by NS _id
if (treatment._id != null) {
@ -299,7 +322,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
DatabaseHelper.updateEarliestDataChange(old.date);
}
scheduleTreatmentChange(treatment);
return true;
return new UpdateReturn(true, true);
}
}
}
@ -307,19 +330,39 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
DatabaseHelper.updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
return true;
return new UpdateReturn(true, true);
}
if (treatment.source == Source.USER) {
getDao().create(treatment);
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
DatabaseHelper.updateEarliestDataChange(treatment.date);
scheduleTreatmentChange(treatment);
return true;
return new UpdateReturn(true, true);
}
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return false;
return new UpdateReturn(false, false);
}
/** Returns the record for the given id, null if none, throws RuntimeException
* if multiple records with the same pump id exist. */
@Nullable
public Treatment getPumpRecordById(long pumpId) {
try {
QueryBuilder<Treatment, Long> queryBuilder = getDao().queryBuilder();
Where where = queryBuilder.where();
where.eq("pumpId", pumpId);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
List<Treatment> result = getDao().query(preparedQuery);
switch (result.size()) {
case 0: return null;
case 1: return result.get(0);
default: throw new RuntimeException("Multiple records with the same pump id found: " + result.toString());
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public void deleteNS(JSONObject json) {
@ -423,4 +466,14 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
public IBinder onBind(Intent intent) {
return null;
}
public class UpdateReturn {
public UpdateReturn(boolean success, boolean newRecord){
this.success = success;
this.newRecord = newRecord;
}
boolean newRecord;
boolean success;
}
}

View file

@ -1,7 +1,9 @@
package info.nightscout.androidaps.plugins.Treatments;
import android.content.Intent;
import android.support.annotation.Nullable;
import com.crashlytics.android.answers.CustomEvent;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger;
@ -38,11 +40,13 @@ import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.SP;
import info.nightscout.utils.T;
@ -465,7 +469,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
// return true if new record is created
@Override
public boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo) {
public boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo, boolean allowUpdate) {
Treatment treatment = new Treatment();
treatment.date = detailedBolusInfo.date;
treatment.source = detailedBolusInfo.source;
@ -477,7 +481,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
treatment.carbs = detailedBolusInfo.carbs;
treatment.source = detailedBolusInfo.source;
treatment.mealBolus = treatment.carbs > 0;
boolean newRecordCreated = getService().createOrUpdate(treatment);
TreatmentService.UpdateReturn creatOrUpdateResult = getService().createOrUpdate(treatment);
boolean newRecordCreated = creatOrUpdateResult.newRecord;
//log.debug("Adding new Treatment record" + treatment.toString());
if (detailedBolusInfo.carbTime != 0) {
Treatment carbsTreatment = new Treatment();
@ -491,6 +496,24 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
}
if (newRecordCreated && detailedBolusInfo.isValid)
NSUpload.uploadTreatmentRecord(detailedBolusInfo);
if (!allowUpdate && !creatOrUpdateResult.success) {
log.error("Treatment could not be added to DB", new Exception());
String status = String.format(MainApp.gs(R.string.error_adding_treatment_message), treatment.insulin, (int) treatment.carbs, DateUtil.dateAndTimeString(treatment.date));
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.error);
i.putExtra("title", MainApp.gs(R.string.error_adding_treatment_title));
i.putExtra("status", status);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
CustomEvent customEvent = new CustomEvent("TreatmentClash");
customEvent.putCustomAttribute("status", status);
FabricPrivacy.getInstance().logCustom(customEvent);
}
return newRecordCreated;
}

View file

@ -719,7 +719,7 @@ public class ActionStringHandler {
}
});
} else {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
}
}

View file

@ -1163,6 +1163,9 @@
<string name="careportal_removestartedevents">Clean AndroidAPS started</string>
<string name="storedsettingsfound">Stored settings found</string>
<string name="allow_hardware_pump_text">Attention: If you activate and connect to a hardware pump, AndroidAPS will copy the basal settings from the profile to the pump, overwriting the existing basal rate stored on the pump. Make sure you have the correct basal setting in AndroidAPS. If you are not sure or don\'t want to overwrite the basal settings on your pump, press cancel and repeat switching to the pump at a later time.</string>
<string name="error_adding_treatment_title">Treatment data incomplete</string>
<!-- TODO convert to proper style -->
<string name="error_adding_treatment_message" formatted="false">A treatment (insulin: %.2f, carbs: %d, at: %s) could not be added to treatments. Please check and manually add a record as appropriate.</string>
<string name="generated_ecarbs_note">Generated eCarbs with amount: %1$dg, duration: %2$dh, delay: %3$dm</string>
<string name="key_plugin_stats_report_timestamp" translatable="false">key_plugin_stats_report_timestamp</string>