Dana plugin refactoring
This commit is contained in:
parent
f54452515b
commit
4cef8db54b
22 changed files with 1030 additions and 2207 deletions
|
@ -0,0 +1,557 @@
|
|||
package info.nightscout.androidaps.plugins.PumpDanaR;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||
import info.nightscout.androidaps.interfaces.DanaRInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.ProfileInterface;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractDanaRExecutionService;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.Round;
|
||||
|
||||
/**
|
||||
* Created by mike on 28.01.2018.
|
||||
*/
|
||||
|
||||
public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface {
|
||||
protected Logger log;
|
||||
|
||||
protected boolean mPluginPumpEnabled = false;
|
||||
protected boolean mPluginProfileEnabled = false;
|
||||
protected boolean mFragmentPumpVisible = true;
|
||||
|
||||
protected AbstractDanaRExecutionService sExecutionService;
|
||||
|
||||
protected DanaRPump pump = DanaRPump.getInstance();
|
||||
protected boolean useExtendedBoluses = false;
|
||||
|
||||
public PumpDescription pumpDescription = new PumpDescription();
|
||||
|
||||
@Override
|
||||
public String getFragmentClass() {
|
||||
return DanaRFragment.class.getName();
|
||||
}
|
||||
|
||||
// Plugin base interface
|
||||
@Override
|
||||
public int getType() {
|
||||
return PluginBase.PUMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameShort() {
|
||||
String name = MainApp.sResources.getString(R.string.danarpump_shortname);
|
||||
if (!name.trim().isEmpty()) {
|
||||
//only if translation exists
|
||||
return name;
|
||||
}
|
||||
// use long name as fallback
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int type) {
|
||||
if (type == PluginBase.PROFILE) return mPluginProfileEnabled && mPluginPumpEnabled;
|
||||
else if (type == PluginBase.PUMP) return mPluginPumpEnabled;
|
||||
else if (type == PluginBase.CONSTRAINTS) return mPluginPumpEnabled;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisibleInTabs(int type) {
|
||||
if (type == PluginBase.PROFILE || type == PluginBase.CONSTRAINTS) return false;
|
||||
else if (type == PluginBase.PUMP) return mFragmentPumpVisible;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeHidden(int type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFragment() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showInList(int type) {
|
||||
return type == PUMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
||||
if (type == PluginBase.PROFILE)
|
||||
mPluginProfileEnabled = fragmentEnabled;
|
||||
else if (type == PluginBase.PUMP)
|
||||
mPluginPumpEnabled = fragmentEnabled;
|
||||
// if pump profile was enabled need to switch to another too
|
||||
if (type == PluginBase.PUMP && !fragmentEnabled && mPluginProfileEnabled) {
|
||||
setFragmentEnabled(PluginBase.PROFILE, false);
|
||||
setFragmentVisible(PluginBase.PROFILE, false);
|
||||
NSProfilePlugin.getPlugin().setFragmentEnabled(PluginBase.PROFILE, true);
|
||||
NSProfilePlugin.getPlugin().setFragmentVisible(PluginBase.PROFILE, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
||||
if (type == PluginBase.PUMP)
|
||||
mFragmentPumpVisible = fragmentVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuspended() {
|
||||
return pump.pumpSuspended;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBusy() {
|
||||
if (sExecutionService == null) return false;
|
||||
return sExecutionService.isConnected() || sExecutionService.isConnecting();
|
||||
}
|
||||
|
||||
// Pump interface
|
||||
@Override
|
||||
public PumpEnactResult setNewBasalProfile(Profile profile) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
|
||||
if (sExecutionService == null) {
|
||||
log.error("setNewBasalProfile sExecutionService is null");
|
||||
result.comment = "setNewBasalProfile sExecutionService is null";
|
||||
return result;
|
||||
}
|
||||
if (!isInitialized()) {
|
||||
log.error("setNewBasalProfile not initialized");
|
||||
Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
result.comment = MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet);
|
||||
return result;
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
|
||||
}
|
||||
if (!sExecutionService.updateBasalsInPump(profile)) {
|
||||
Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.sResources.getString(R.string.failedupdatebasalprofile), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
result.comment = MainApp.sResources.getString(R.string.failedupdatebasalprofile);
|
||||
return result;
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE));
|
||||
Notification notification = new Notification(Notification.PROFILE_SET_OK, MainApp.sResources.getString(R.string.profile_set_ok), Notification.INFO, 60);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
result.success = true;
|
||||
result.enacted = true;
|
||||
result.comment = "OK";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThisProfileSet(Profile profile) {
|
||||
if (!isInitialized())
|
||||
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
|
||||
if (pump.pumpProfiles == null)
|
||||
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
|
||||
int basalValues = pump.basal48Enable ? 48 : 24;
|
||||
int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60;
|
||||
for (int h = 0; h < basalValues; h++) {
|
||||
Double pumpValue = pump.pumpProfiles[pump.activeProfile][h];
|
||||
Double profileValue = profile.getBasal((Integer) (h * basalIncrement));
|
||||
if (profileValue == null) return true;
|
||||
if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) {
|
||||
log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date lastDataTime() {
|
||||
return new Date(pump.lastConnection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBaseBasalRate() {
|
||||
return pump.currentBasal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopBolusDelivering() {
|
||||
if (sExecutionService == null) {
|
||||
log.error("stopBolusDelivering sExecutionService is null");
|
||||
return;
|
||||
}
|
||||
sExecutionService.bolusStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
|
||||
percent = configBuilderPlugin.applyBasalConstraints(percent);
|
||||
if (percent < 0) {
|
||||
result.isTempCancel = false;
|
||||
result.enacted = false;
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
|
||||
log.error("setTempBasalPercent: Invalid input");
|
||||
return result;
|
||||
}
|
||||
if (percent > getPumpDescription().maxTempPercent)
|
||||
percent = getPumpDescription().maxTempPercent;
|
||||
TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (runningTB != null && runningTB.percentRate == percent && !enforceNew) {
|
||||
result.enacted = false;
|
||||
result.success = true;
|
||||
result.isTempCancel = false;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.duration = pump.tempBasalRemainingMin;
|
||||
result.percent = pump.tempBasalPercent;
|
||||
result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory();
|
||||
result.isPercent = true;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setTempBasalPercent: Correct value already set");
|
||||
return result;
|
||||
}
|
||||
int durationInHours = Math.max(durationInMinutes / 60, 1);
|
||||
boolean connectionOK = sExecutionService.tempBasal(percent, durationInHours);
|
||||
if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) {
|
||||
result.enacted = true;
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.isTempCancel = false;
|
||||
result.duration = pump.tempBasalRemainingMin;
|
||||
result.percent = pump.tempBasalPercent;
|
||||
result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory();
|
||||
result.isPercent = true;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setTempBasalPercent: OK");
|
||||
return result;
|
||||
}
|
||||
result.enacted = false;
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.tempbasaldeliveryerror);
|
||||
log.error("setTempBasalPercent: Failed to set temp basal");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
|
||||
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
|
||||
insulin = configBuilderPlugin.applyBolusConstraints(insulin);
|
||||
// needs to be rounded
|
||||
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
|
||||
insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep);
|
||||
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) {
|
||||
result.enacted = false;
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.duration = pump.extendedBolusRemainingMinutes;
|
||||
result.absolute = pump.extendedBolusAbsoluteRate;
|
||||
result.isPercent = false;
|
||||
result.isTempCancel = false;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin);
|
||||
return result;
|
||||
}
|
||||
boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours);
|
||||
if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) {
|
||||
result.enacted = true;
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.isTempCancel = false;
|
||||
result.duration = pump.extendedBolusRemainingMinutes;
|
||||
result.absolute = pump.extendedBolusAbsoluteRate;
|
||||
result.bolusDelivered = pump.extendedBolusAmount;
|
||||
result.isPercent = false;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setExtendedBolus: OK");
|
||||
return result;
|
||||
}
|
||||
result.enacted = false;
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
|
||||
log.error("setExtendedBolus: Failed to extended bolus");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult cancelExtendedBolus() {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (runningEB != null) {
|
||||
sExecutionService.extendedBolusStop();
|
||||
result.enacted = true;
|
||||
result.isTempCancel = true;
|
||||
}
|
||||
if (!pump.isExtendedInProgress) {
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
if (Config.logPumpActions)
|
||||
log.debug("cancelExtendedBolus: OK");
|
||||
return result;
|
||||
} else {
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
|
||||
log.error("cancelExtendedBolus: Failed to cancel extended bolus");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(String from) {
|
||||
if (sExecutionService != null) {
|
||||
sExecutionService.connect();
|
||||
pumpDescription.basalStep = pump.basalStep;
|
||||
pumpDescription.bolusStep = pump.bolusStep;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return sExecutionService != null && sExecutionService.isConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnecting() {
|
||||
return sExecutionService != null && sExecutionService.isConnecting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String from) {
|
||||
if (sExecutionService != null) sExecutionService.disconnect(from);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopConnecting() {
|
||||
if (sExecutionService != null) sExecutionService.stopConnecting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPumpStatus() {
|
||||
if (sExecutionService != null) sExecutionService.getPumpStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getJSONStatus() {
|
||||
if (pump.lastConnection + 5 * 60 * 1000L < System.currentTimeMillis()) {
|
||||
return null;
|
||||
}
|
||||
JSONObject pumpjson = new JSONObject();
|
||||
JSONObject battery = new JSONObject();
|
||||
JSONObject status = new JSONObject();
|
||||
JSONObject extended = new JSONObject();
|
||||
try {
|
||||
battery.put("percent", pump.batteryRemaining);
|
||||
status.put("status", pump.pumpSuspended ? "suspended" : "normal");
|
||||
status.put("timestamp", DateUtil.toISOString(pump.lastConnection));
|
||||
extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION);
|
||||
extended.put("PumpIOB", pump.iob);
|
||||
if (pump.lastBolusTime.getTime() != 0) {
|
||||
extended.put("LastBolus", pump.lastBolusTime.toLocaleString());
|
||||
extended.put("LastBolusAmount", pump.lastBolusAmount);
|
||||
}
|
||||
TemporaryBasal tb = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (tb != null) {
|
||||
extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis()));
|
||||
extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date));
|
||||
extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes());
|
||||
}
|
||||
ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (eb != null) {
|
||||
extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate());
|
||||
extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date));
|
||||
extended.put("ExtendedBolusRemaining", eb.getPlannedRemainingMinutes());
|
||||
}
|
||||
extended.put("BaseBasalRate", getBaseBasalRate());
|
||||
try {
|
||||
extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
pumpjson.put("battery", battery);
|
||||
pumpjson.put("status", status);
|
||||
pumpjson.put("extended", extended);
|
||||
pumpjson.put("reservoir", (int) pump.reservoirRemainingUnits);
|
||||
pumpjson.put("clock", DateUtil.toISOString(new Date()));
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return pumpjson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceID() {
|
||||
return pump.serialNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpDescription getPumpDescription() {
|
||||
return pumpDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* DanaR interface
|
||||
*/
|
||||
|
||||
@Override
|
||||
public PumpEnactResult loadHistory(byte type) {
|
||||
return sExecutionService.loadHistory(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constraint interface
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isLoopEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosedModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutosensModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAMAModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSMBModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Double applyBasalConstraints(Double absoluteRate) {
|
||||
double origAbsoluteRate = absoluteRate;
|
||||
if (pump != null) {
|
||||
if (absoluteRate > pump.maxBasal) {
|
||||
absoluteRate = pump.maxBasal;
|
||||
if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit)
|
||||
log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h");
|
||||
}
|
||||
}
|
||||
return absoluteRate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Integer applyBasalConstraints(Integer percentRate) {
|
||||
Integer origPercentRate = percentRate;
|
||||
if (percentRate < 0) percentRate = 0;
|
||||
if (percentRate > getPumpDescription().maxTempPercent)
|
||||
percentRate = getPumpDescription().maxTempPercent;
|
||||
if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
||||
log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%");
|
||||
return percentRate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Double applyBolusConstraints(Double insulin) {
|
||||
double origInsulin = insulin;
|
||||
if (pump != null) {
|
||||
if (insulin > pump.maxBolus) {
|
||||
insulin = pump.maxBolus;
|
||||
if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit)
|
||||
log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U");
|
||||
}
|
||||
}
|
||||
return insulin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer applyCarbsConstraints(Integer carbs) {
|
||||
return carbs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double applyMaxIOBConstraints(Double maxIob) {
|
||||
return maxIob;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ProfileStore getProfile() {
|
||||
if (pump.lastSettingsRead == 0)
|
||||
return null; // no info now
|
||||
return pump.createConvertedProfile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnits() {
|
||||
return pump.getUnits();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProfileName() {
|
||||
return pump.createConvertedProfileName();
|
||||
}
|
||||
|
||||
// Reply for sms communicator
|
||||
public String shortStatus(boolean veryShort) {
|
||||
String ret = "";
|
||||
if (pump.lastConnection != 0) {
|
||||
Long agoMsec = System.currentTimeMillis() - pump.lastConnection;
|
||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
||||
ret += "LastConn: " + agoMin + " minago\n";
|
||||
}
|
||||
if (pump.lastBolusTime.getTime() != 0) {
|
||||
ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n";
|
||||
}
|
||||
if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) {
|
||||
ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n";
|
||||
}
|
||||
if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n";
|
||||
}
|
||||
if (!veryShort) {
|
||||
ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n";
|
||||
}
|
||||
ret += "IOB: " + pump.iob + "U\n";
|
||||
ret += "Reserv: " + DecimalFormatter.to0Decimal(pump.reservoirRemainingUnits) + "U\n";
|
||||
ret += "Batt: " + pump.batteryRemaining + "\n";
|
||||
return ret;
|
||||
}
|
||||
// TODO: daily total constraint
|
||||
|
||||
}
|
|
@ -21,6 +21,8 @@ import com.squareup.otto.Subscribe;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
@ -120,6 +122,7 @@ public class DanaRFragment extends SubscriberFragment {
|
|||
|
||||
@OnClick(R.id.danar_btconnection) void onBtConnectionClick() {
|
||||
log.debug("Clicked connect to pump");
|
||||
DanaRPump.getInstance().lastConnection = 0;
|
||||
ConfigBuilderPlugin.getCommandQueue().readStatus("Clicked connect to pump", null);
|
||||
}
|
||||
|
||||
|
@ -181,8 +184,8 @@ public class DanaRFragment extends SubscriberFragment {
|
|||
@Override
|
||||
public void run() {
|
||||
DanaRPump pump = DanaRPump.getInstance();
|
||||
if (pump.lastConnection.getTime() != 0) {
|
||||
Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime();
|
||||
if (pump.lastConnection != 0) {
|
||||
Long agoMsec = System.currentTimeMillis() - pump.lastConnection;
|
||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
||||
lastConnectionView.setText(DateUtil.timeString(pump.lastConnection) + " (" + String.format(MainApp.sResources.getString(R.string.minago), agoMin) + ")");
|
||||
SetWarnColor.setColor(lastConnectionView, agoMin, 16d, 31d);
|
||||
|
|
|
@ -5,69 +5,30 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||
import info.nightscout.androidaps.interfaces.DanaRInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.ProfileInterface;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.services.DanaRExecutionService;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.Round;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.08.2016.
|
||||
*/
|
||||
public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(DanaRPlugin.class);
|
||||
|
||||
@Override
|
||||
public String getFragmentClass() {
|
||||
return DanaRFragment.class.getName();
|
||||
}
|
||||
|
||||
private static boolean fragmentPumpEnabled = false;
|
||||
private static boolean fragmentProfileEnabled = false;
|
||||
private static boolean fragmentPumpVisible = true;
|
||||
|
||||
private static DanaRExecutionService sExecutionService;
|
||||
|
||||
|
||||
private static DanaRPump pump = DanaRPump.getInstance();
|
||||
private static boolean useExtendedBoluses = false;
|
||||
public class DanaRPlugin extends AbstractDanaRPlugin {
|
||||
|
||||
private static DanaRPlugin plugin = null;
|
||||
|
||||
|
@ -77,9 +38,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
|
|||
return plugin;
|
||||
}
|
||||
|
||||
public static PumpDescription pumpDescription = new PumpDescription();
|
||||
|
||||
public DanaRPlugin() {
|
||||
log = LoggerFactory.getLogger(DanaRPlugin.class);
|
||||
useExtendedBoluses = SP.getBoolean("danar_useextended", false);
|
||||
|
||||
Context context = MainApp.instance().getApplicationContext();
|
||||
|
@ -147,83 +107,17 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
|
|||
}
|
||||
|
||||
// Plugin base interface
|
||||
@Override
|
||||
public int getType() {
|
||||
return PluginBase.PUMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return MainApp.instance().getString(R.string.danarpump);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameShort() {
|
||||
String name = MainApp.sResources.getString(R.string.danarpump_shortname);
|
||||
if (!name.trim().isEmpty()) {
|
||||
//only if translation exists
|
||||
return name;
|
||||
}
|
||||
// use long name as fallback
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int type) {
|
||||
if (type == PluginBase.PROFILE) return fragmentProfileEnabled && fragmentPumpEnabled;
|
||||
else if (type == PluginBase.PUMP) return fragmentPumpEnabled;
|
||||
else if (type == PluginBase.CONSTRAINTS) return fragmentPumpEnabled;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisibleInTabs(int type) {
|
||||
if (type == PluginBase.PROFILE || type == PluginBase.CONSTRAINTS) return false;
|
||||
else if (type == PluginBase.PUMP) return fragmentPumpVisible;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeHidden(int type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFragment() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showInList(int type) {
|
||||
return type == PUMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
||||
if (type == PluginBase.PROFILE)
|
||||
fragmentProfileEnabled = fragmentEnabled;
|
||||
else if (type == PluginBase.PUMP)
|
||||
fragmentPumpEnabled = fragmentEnabled;
|
||||
// if pump profile was enabled need to switch to another too
|
||||
if (type == PluginBase.PUMP && !fragmentEnabled && fragmentProfileEnabled) {
|
||||
setFragmentEnabled(PluginBase.PROFILE, false);
|
||||
setFragmentVisible(PluginBase.PROFILE, false);
|
||||
NSProfilePlugin.getPlugin().setFragmentEnabled(PluginBase.PROFILE, true);
|
||||
NSProfilePlugin.getPlugin().setFragmentVisible(PluginBase.PROFILE, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
||||
if (type == PluginBase.PUMP)
|
||||
fragmentPumpVisible = fragmentVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferencesId() {
|
||||
return R.xml.pref_danar;
|
||||
}
|
||||
|
||||
// Pump interface
|
||||
@Override
|
||||
public boolean isFakingTempsByExtendedBoluses() {
|
||||
return useExtendedBoluses;
|
||||
|
@ -231,82 +125,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
|
|||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return pump.lastConnection.getTime() > 0 && pump.isExtendedBolusEnabled && pump.maxBasal > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuspended() {
|
||||
return pump.pumpSuspended;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBusy() {
|
||||
if (sExecutionService == null) return false;
|
||||
return sExecutionService.isConnected() || sExecutionService.isConnecting();
|
||||
}
|
||||
|
||||
// Pump interface
|
||||
@Override
|
||||
public PumpEnactResult setNewBasalProfile(Profile profile) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
|
||||
if (sExecutionService == null) {
|
||||
log.error("setNewBasalProfile sExecutionService is null");
|
||||
result.comment = "setNewBasalProfile sExecutionService is null";
|
||||
return result;
|
||||
}
|
||||
if (!isInitialized()) {
|
||||
log.error("setNewBasalProfile not initialized");
|
||||
Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
result.comment = MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet);
|
||||
return result;
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
|
||||
}
|
||||
if (!sExecutionService.updateBasalsInPump(profile)) {
|
||||
Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.sResources.getString(R.string.failedupdatebasalprofile), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
result.comment = MainApp.sResources.getString(R.string.failedupdatebasalprofile);
|
||||
return result;
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE));
|
||||
result.success = true;
|
||||
result.enacted = true;
|
||||
result.comment = "OK";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThisProfileSet(Profile profile) {
|
||||
if (!isInitialized())
|
||||
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
|
||||
if (pump.pumpProfiles == null)
|
||||
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
|
||||
int basalValues = pump.basal48Enable ? 48 : 24;
|
||||
int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60;
|
||||
for (int h = 0; h < basalValues; h++) {
|
||||
Double pumpValue = pump.pumpProfiles[pump.activeProfile][h];
|
||||
Double profileValue = profile.getBasal((Integer) (h * basalIncrement));
|
||||
if (profileValue == null) return true;
|
||||
if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) {
|
||||
log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date lastDataTime() {
|
||||
return pump.lastConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBaseBasalRate() {
|
||||
return pump.currentBasal;
|
||||
return pump.lastConnection > 0 && pump.isExtendedBolusEnabled && pump.maxBasal > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -316,7 +135,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
|
|||
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
|
||||
Treatment t = new Treatment();
|
||||
boolean connectionOK = false;
|
||||
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, t);
|
||||
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t);
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
result.success = connectionOK;
|
||||
result.bolusDelivered = t.insulin;
|
||||
|
@ -339,15 +158,6 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopBolusDelivering() {
|
||||
if (sExecutionService == null) {
|
||||
log.error("stopBolusDelivering sExecutionService is null");
|
||||
return;
|
||||
}
|
||||
sExecutionService.bolusStop();
|
||||
}
|
||||
|
||||
// This is called from APS
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) {
|
||||
|
@ -500,100 +310,6 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
|
||||
percent = configBuilderPlugin.applyBasalConstraints(percent);
|
||||
if (percent < 0) {
|
||||
result.isTempCancel = false;
|
||||
result.enacted = false;
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
|
||||
log.error("setTempBasalPercent: Invalid input");
|
||||
return result;
|
||||
}
|
||||
if (percent > getPumpDescription().maxTempPercent)
|
||||
percent = getPumpDescription().maxTempPercent;
|
||||
TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (runningTB != null && runningTB.percentRate == percent && !enforceNew) {
|
||||
result.enacted = false;
|
||||
result.success = true;
|
||||
result.isTempCancel = false;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.duration = pump.tempBasalRemainingMin;
|
||||
result.percent = pump.tempBasalPercent;
|
||||
result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory();
|
||||
result.isPercent = true;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setTempBasalPercent: Correct value already set");
|
||||
return result;
|
||||
}
|
||||
int durationInHours = Math.max(durationInMinutes / 60, 1);
|
||||
boolean connectionOK = sExecutionService.tempBasal(percent, durationInHours);
|
||||
if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) {
|
||||
result.enacted = true;
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.isTempCancel = false;
|
||||
result.duration = pump.tempBasalRemainingMin;
|
||||
result.percent = pump.tempBasalPercent;
|
||||
result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory();
|
||||
result.isPercent = true;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setTempBasalPercent: OK");
|
||||
return result;
|
||||
}
|
||||
result.enacted = false;
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.tempbasaldeliveryerror);
|
||||
log.error("setTempBasalPercent: Failed to set temp basal");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
|
||||
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
|
||||
insulin = configBuilderPlugin.applyBolusConstraints(insulin);
|
||||
// needs to be rounded
|
||||
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
|
||||
insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep);
|
||||
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) {
|
||||
result.enacted = false;
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.duration = pump.extendedBolusRemainingMinutes;
|
||||
result.absolute = pump.extendedBolusAbsoluteRate;
|
||||
result.isPercent = false;
|
||||
result.isTempCancel = false;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin);
|
||||
return result;
|
||||
}
|
||||
boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours);
|
||||
if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) {
|
||||
result.enacted = true;
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.isTempCancel = false;
|
||||
result.duration = pump.extendedBolusRemainingMinutes;
|
||||
result.absolute = pump.extendedBolusAbsoluteRate;
|
||||
result.bolusDelivered = pump.extendedBolusAmount;
|
||||
result.isPercent = false;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setExtendedBolus: OK");
|
||||
return result;
|
||||
}
|
||||
result.enacted = false;
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
|
||||
log.error("setExtendedBolus: Failed to extended bolus");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult cancelTempBasal(boolean force) {
|
||||
if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress())
|
||||
|
@ -634,257 +350,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult cancelExtendedBolus() {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (runningEB != null) {
|
||||
sExecutionService.extendedBolusStop();
|
||||
result.enacted = true;
|
||||
result.isTempCancel = true;
|
||||
}
|
||||
if (!pump.isExtendedInProgress) {
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
if (Config.logPumpActions)
|
||||
log.debug("cancelExtendedBolus: OK");
|
||||
return result;
|
||||
} else {
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
|
||||
log.error("cancelExtendedBolus: Failed to cancel extended bolus");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(String from) {
|
||||
if (sExecutionService != null) {
|
||||
sExecutionService.connect(from);
|
||||
pumpDescription.basalStep = pump.basalStep;
|
||||
pumpDescription.bolusStep = pump.bolusStep;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return sExecutionService != null && sExecutionService.isConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnecting() {
|
||||
return sExecutionService != null && sExecutionService.isConnecting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String from) {
|
||||
if (sExecutionService != null) sExecutionService.disconnect(from);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopConnecting() {
|
||||
if (sExecutionService != null) sExecutionService.stopConnecting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPumpStatus() {
|
||||
if (sExecutionService != null) sExecutionService.getPumpStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getJSONStatus() {
|
||||
if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) {
|
||||
return null;
|
||||
}
|
||||
JSONObject pumpjson = new JSONObject();
|
||||
JSONObject battery = new JSONObject();
|
||||
JSONObject status = new JSONObject();
|
||||
JSONObject extended = new JSONObject();
|
||||
try {
|
||||
battery.put("percent", pump.batteryRemaining);
|
||||
status.put("status", pump.pumpSuspended ? "suspended" : "normal");
|
||||
status.put("timestamp", DateUtil.toISOString(pump.lastConnection));
|
||||
extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION);
|
||||
extended.put("PumpIOB", pump.iob);
|
||||
if (pump.lastBolusTime.getTime() != 0) {
|
||||
extended.put("LastBolus", pump.lastBolusTime.toLocaleString());
|
||||
extended.put("LastBolusAmount", pump.lastBolusAmount);
|
||||
}
|
||||
TemporaryBasal tb = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (tb != null) {
|
||||
extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis()));
|
||||
extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date));
|
||||
extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes());
|
||||
}
|
||||
ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (eb != null) {
|
||||
extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate());
|
||||
extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date));
|
||||
extended.put("ExtendedBolusRemaining", eb.getPlannedRemainingMinutes());
|
||||
}
|
||||
extended.put("BaseBasalRate", getBaseBasalRate());
|
||||
try {
|
||||
extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
pumpjson.put("battery", battery);
|
||||
pumpjson.put("status", status);
|
||||
pumpjson.put("extended", extended);
|
||||
pumpjson.put("reservoir", (int) pump.reservoirRemainingUnits);
|
||||
pumpjson.put("clock", DateUtil.toISOString(new Date()));
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return pumpjson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceID() {
|
||||
return pump.serialNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpDescription getPumpDescription() {
|
||||
return pumpDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* DanaR interface
|
||||
*/
|
||||
|
||||
@Override
|
||||
public PumpEnactResult loadHistory(byte type) {
|
||||
return sExecutionService.loadHistory(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult loadEvents() {
|
||||
return null; // no history, not needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Constraint interface
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isLoopEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosedModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutosensModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAMAModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSMBModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Double applyBasalConstraints(Double absoluteRate) {
|
||||
double origAbsoluteRate = absoluteRate;
|
||||
if (pump != null) {
|
||||
if (absoluteRate > pump.maxBasal) {
|
||||
absoluteRate = pump.maxBasal;
|
||||
if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit)
|
||||
log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h");
|
||||
}
|
||||
}
|
||||
return absoluteRate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Integer applyBasalConstraints(Integer percentRate) {
|
||||
Integer origPercentRate = percentRate;
|
||||
if (percentRate < 0) percentRate = 0;
|
||||
if (percentRate > getPumpDescription().maxTempPercent)
|
||||
percentRate = getPumpDescription().maxTempPercent;
|
||||
if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
||||
log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%");
|
||||
return percentRate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Double applyBolusConstraints(Double insulin) {
|
||||
double origInsulin = insulin;
|
||||
if (pump != null) {
|
||||
if (insulin > pump.maxBolus) {
|
||||
insulin = pump.maxBolus;
|
||||
if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit)
|
||||
log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U");
|
||||
}
|
||||
}
|
||||
return insulin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer applyCarbsConstraints(Integer carbs) {
|
||||
return carbs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double applyMaxIOBConstraints(Double maxIob) {
|
||||
return maxIob;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ProfileStore getProfile() {
|
||||
if (pump.lastSettingsRead.getTime() == 0)
|
||||
return null; // no info now
|
||||
return pump.createConvertedProfile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnits() {
|
||||
return pump.getUnits();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProfileName() {
|
||||
return pump.createConvertedProfileName();
|
||||
}
|
||||
|
||||
// Reply for sms communicator
|
||||
public String shortStatus(boolean veryShort) {
|
||||
String ret = "";
|
||||
if (pump.lastConnection.getTime() != 0) {
|
||||
Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime();
|
||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
||||
ret += "LastConn: " + agoMin + " minago\n";
|
||||
}
|
||||
if (pump.lastBolusTime.getTime() != 0) {
|
||||
ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n";
|
||||
}
|
||||
if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) {
|
||||
ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n";
|
||||
}
|
||||
if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n";
|
||||
}
|
||||
if (!veryShort) {
|
||||
ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n";
|
||||
}
|
||||
ret += "IOB: " + pump.iob + "U\n";
|
||||
ret += "Reserv: " + DecimalFormatter.to0Decimal(pump.reservoirRemainingUnits) + "U\n";
|
||||
ret += "Batt: " + pump.batteryRemaining + "\n";
|
||||
return ret;
|
||||
}
|
||||
// TODO: daily total constraint
|
||||
|
||||
}
|
||||
|
|
|
@ -56,8 +56,8 @@ public class DanaRPump {
|
|||
public static final int CARBS = 14;
|
||||
public static final int PRIMECANNULA = 15;
|
||||
|
||||
public Date lastConnection = new Date(0);
|
||||
public Date lastSettingsRead = new Date(0);
|
||||
public long lastConnection = 0;
|
||||
public long lastSettingsRead =0;
|
||||
|
||||
// Info
|
||||
public String serialNumber = "";
|
||||
|
|
|
@ -13,12 +13,13 @@ import java.io.OutputStream;
|
|||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageHashTable;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractSerialIOThread;
|
||||
import info.nightscout.utils.CRC;
|
||||
|
||||
/**
|
||||
* Created by mike on 17.07.2016.
|
||||
*/
|
||||
public class SerialIOThread extends Thread {
|
||||
public class SerialIOThread extends AbstractSerialIOThread {
|
||||
private static Logger log = LoggerFactory.getLogger(SerialIOThread.class);
|
||||
|
||||
private InputStream mInputStream = null;
|
||||
|
@ -28,10 +29,10 @@ public class SerialIOThread extends Thread {
|
|||
private boolean mKeepRunning = true;
|
||||
private byte[] mReadBuff = new byte[0];
|
||||
|
||||
MessageBase processedMessage;
|
||||
private MessageBase processedMessage;
|
||||
|
||||
public SerialIOThread(BluetoothSocket rfcommSocket) {
|
||||
super(SerialIOThread.class.toString());
|
||||
super();
|
||||
|
||||
mRfCommSocket = rfcommSocket;
|
||||
try {
|
||||
|
@ -137,6 +138,7 @@ public class SerialIOThread extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void sendMessage(MessageBase message) {
|
||||
if (!mRfCommSocket.isConnected()) {
|
||||
log.error("Socket not connected on sendMessage");
|
||||
|
@ -172,6 +174,7 @@ public class SerialIOThread extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String reason) {
|
||||
mKeepRunning = false;
|
||||
try {
|
||||
|
|
|
@ -35,8 +35,8 @@ public class MsgInitConnStatusTime extends MessageBase {
|
|||
MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginBase.PUMP, true);
|
||||
MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentEnabled(PluginBase.PUMP, false);
|
||||
MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentVisible(PluginBase.PUMP, false);
|
||||
DanaRPump.getInstance().lastConnection = new Date(0); // mark not initialized
|
||||
|
||||
DanaRPump.getInstance().lastConnection = 0; // mark not initialized
|
||||
//If profile coming from pump, switch it as well
|
||||
if(MainApp.getSpecificPlugin(DanaRPlugin.class).isEnabled(PluginBase.PROFILE)){
|
||||
(MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, false);
|
||||
|
|
|
@ -23,7 +23,7 @@ public class MsgSettingBasal extends MessageBase {
|
|||
pump.pumpProfiles[pump.activeProfile] = new double[24];
|
||||
for (int index = 0; index < 24; index++) {
|
||||
int basal = intFromBuff(bytes, 2 * index, 2);
|
||||
if (basal < DanaRPlugin.pumpDescription.basalMinimumRate) basal = 0;
|
||||
if (basal < DanaRPlugin.getPlugin().pumpDescription.basalMinimumRate) basal = 0;
|
||||
pump.pumpProfiles[pump.activeProfile][index] = basal / 100d;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,12 @@ import org.slf4j.LoggerFactory;
|
|||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
|
||||
|
||||
/**
|
||||
* Created by mike on 13.12.2016.
|
||||
|
@ -40,6 +42,11 @@ public class MsgSettingMeal extends MessageBase {
|
|||
log.debug("Is Config U/d: " + pump.isConfigUD);
|
||||
}
|
||||
|
||||
// DanaRKorean is not possible to set to 0.01 but it works when controlled from AAPS
|
||||
if (DanaRKoreanPlugin.getPlugin().isEnabled(PluginBase.PUMP)) {
|
||||
pump.basalStep = 0.01d;
|
||||
}
|
||||
|
||||
if (pump.basalStep != 0.01d) {
|
||||
Notification notification = new Notification(Notification.WRONGBASALSTEP, MainApp.sResources.getString(R.string.danar_setbasalstep001), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
|
|
|
@ -0,0 +1,225 @@
|
|||
package info.nightscout.androidaps.plugins.PumpDanaR.services;
|
||||
|
||||
import android.app.Service;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothSocket;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.EventPumpStatusChanged;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.SerialIOThread;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStop;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryAlarm;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBasalHour;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBolus;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryCarbo;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDailyInsulin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDone;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryError;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryGlucose;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryRefill;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistorySuspend;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStart;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStop;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
/**
|
||||
* Created by mike on 28.01.2018.
|
||||
*/
|
||||
|
||||
public abstract class AbstractDanaRExecutionService extends Service {
|
||||
protected Logger log;
|
||||
|
||||
protected String mDevName;
|
||||
|
||||
protected BluetoothSocket mRfcommSocket;
|
||||
protected BluetoothDevice mBTDevice;
|
||||
|
||||
protected DanaRPump mDanaRPump = DanaRPump.getInstance();
|
||||
protected Treatment mBolusingTreatment = null;
|
||||
|
||||
protected Boolean mConnectionInProgress = false;
|
||||
|
||||
protected AbstractSerialIOThread mSerialIOThread;
|
||||
|
||||
protected IBinder mBinder;
|
||||
|
||||
protected final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
|
||||
|
||||
public abstract boolean updateBasalsInPump(final Profile profile);
|
||||
|
||||
public abstract void connect();
|
||||
|
||||
public abstract void getPumpStatus();
|
||||
|
||||
public abstract PumpEnactResult loadEvents();
|
||||
|
||||
public abstract boolean bolus(double amount, int carbs, long carbtime, final Treatment t);
|
||||
|
||||
public abstract boolean highTempBasal(int percent); // Rv2 only
|
||||
|
||||
public abstract boolean tempBasal(int percent, int durationInHours);
|
||||
|
||||
public abstract boolean tempBasalStop();
|
||||
|
||||
public abstract boolean extendedBolus(double insulin, int durationInHalfHours);
|
||||
|
||||
public abstract boolean extendedBolusStop();
|
||||
|
||||
|
||||
protected BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
String action = intent.getAction();
|
||||
if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
|
||||
log.debug("Device was disconnected " + device.getName());//Device was disconnected
|
||||
if (mBTDevice != null && mBTDevice.getName() != null && mBTDevice.getName().equals(device.getName())) {
|
||||
if (mSerialIOThread != null) {
|
||||
mSerialIOThread.disconnect("BT disconnection broadcast");
|
||||
}
|
||||
MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return mRfcommSocket != null && mRfcommSocket.isConnected();
|
||||
}
|
||||
|
||||
public boolean isConnecting() {
|
||||
return mConnectionInProgress;
|
||||
}
|
||||
|
||||
public void disconnect(String from) {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect(from);
|
||||
}
|
||||
|
||||
public void stopConnecting() {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect("stopConnecting");
|
||||
}
|
||||
|
||||
protected void getBTSocketForSelectedPump() {
|
||||
mDevName = SP.getString(MainApp.sResources.getString(R.string.key_danar_bt_name), "");
|
||||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
|
||||
if (bluetoothAdapter != null) {
|
||||
Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
|
||||
|
||||
for (BluetoothDevice device : bondedDevices) {
|
||||
if (mDevName.equals(device.getName())) {
|
||||
mBTDevice = device;
|
||||
try {
|
||||
mRfcommSocket = mBTDevice.createRfcommSocketToServiceRecord(SPP_UUID);
|
||||
} catch (IOException e) {
|
||||
log.error("Error creating socket: ", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.nobtadapter));
|
||||
}
|
||||
if (mBTDevice == null) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.devicenotfound));
|
||||
}
|
||||
}
|
||||
|
||||
public void bolusStop() {
|
||||
if (Config.logDanaBTComm)
|
||||
log.debug("bolusStop >>>>> @ " + (mBolusingTreatment == null ? "" : mBolusingTreatment.insulin));
|
||||
MsgBolusStop stop = new MsgBolusStop();
|
||||
stop.forced = true;
|
||||
if (isConnected()) {
|
||||
mSerialIOThread.sendMessage(stop);
|
||||
while (!stop.stopped) {
|
||||
mSerialIOThread.sendMessage(stop);
|
||||
SystemClock.sleep(200);
|
||||
}
|
||||
} else {
|
||||
stop.stopped = true;
|
||||
}
|
||||
}
|
||||
|
||||
public PumpEnactResult loadHistory(byte type) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
if (!isConnected()) return result;
|
||||
MessageBase msg = null;
|
||||
switch (type) {
|
||||
case RecordTypes.RECORD_TYPE_ALARM:
|
||||
msg = new MsgHistoryAlarm();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_BASALHOUR:
|
||||
msg = new MsgHistoryBasalHour();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_BOLUS:
|
||||
msg = new MsgHistoryBolus();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_CARBO:
|
||||
msg = new MsgHistoryCarbo();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_DAILY:
|
||||
msg = new MsgHistoryDailyInsulin();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_ERROR:
|
||||
msg = new MsgHistoryError();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_GLUCOSE:
|
||||
msg = new MsgHistoryGlucose();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_REFILL:
|
||||
msg = new MsgHistoryRefill();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_SUSPEND:
|
||||
msg = new MsgHistorySuspend();
|
||||
break;
|
||||
}
|
||||
MsgHistoryDone done = new MsgHistoryDone();
|
||||
mSerialIOThread.sendMessage(new MsgPCCommStart());
|
||||
SystemClock.sleep(400);
|
||||
mSerialIOThread.sendMessage(msg);
|
||||
while (!done.received && mRfcommSocket.isConnected()) {
|
||||
SystemClock.sleep(100);
|
||||
}
|
||||
SystemClock.sleep(200);
|
||||
mSerialIOThread.sendMessage(new MsgPCCommStop());
|
||||
result.success = true;
|
||||
result.comment = "OK";
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package info.nightscout.androidaps.plugins.PumpDanaR.services;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase;
|
||||
|
||||
/**
|
||||
* Created by mike on 28.01.2018.
|
||||
*/
|
||||
|
||||
public abstract class AbstractSerialIOThread extends Thread {
|
||||
|
||||
public abstract void sendMessage(MessageBase message);
|
||||
public abstract void disconnect(String reason);
|
||||
}
|
|
@ -1,41 +1,33 @@
|
|||
package info.nightscout.androidaps.plugins.PumpDanaR.services;
|
||||
|
||||
import android.app.Service;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothSocket;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventInitializationChanged;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.events.EventPumpStatusChanged;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.SerialIOThread;
|
||||
|
@ -45,18 +37,6 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStart;
|
|||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStartWithSpeed;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStop;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgCheckValue;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryAlarm;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBasalHour;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBolus;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryCarbo;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDailyInsulin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDone;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryError;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryGlucose;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryRefill;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistorySuspend;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStart;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStop;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetActivateBasalProfile;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetBasalProfile;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetCarbsEntry;
|
||||
|
@ -67,9 +47,9 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStop;
|
|||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTime;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingActiveProfile;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingBasal;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMeal;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingGlucose;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMaxValues;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMeal;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatios;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatiosAll;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingPumpTime;
|
||||
|
@ -78,51 +58,18 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatus;
|
|||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBasic;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBolusExtended;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusTempBasal;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
public class DanaRExecutionService extends Service {
|
||||
private static Logger log = LoggerFactory.getLogger(DanaRExecutionService.class);
|
||||
|
||||
private String devName;
|
||||
|
||||
private SerialIOThread mSerialIOThread;
|
||||
private BluetoothSocket mRfcommSocket;
|
||||
private BluetoothDevice mBTDevice;
|
||||
|
||||
private IBinder mBinder = new LocalBinder();
|
||||
|
||||
private DanaRPump danaRPump = DanaRPump.getInstance();
|
||||
private Treatment bolusingTreatment = null;
|
||||
|
||||
private static Boolean connectionInProgress = false;
|
||||
|
||||
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
|
||||
|
||||
private BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
String action = intent.getAction();
|
||||
if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
|
||||
log.debug("Device was disconnected " + device.getName());//Device was disconnected
|
||||
if (mBTDevice != null && mBTDevice.getName() != null && mBTDevice.getName().equals(device.getName())) {
|
||||
if (mSerialIOThread != null) {
|
||||
mSerialIOThread.disconnect("BT disconnection broadcast");
|
||||
}
|
||||
MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
public class DanaRExecutionService extends AbstractDanaRExecutionService{
|
||||
|
||||
public DanaRExecutionService() {
|
||||
log = LoggerFactory.getLogger(DanaRExecutionService.class);
|
||||
mBinder = new LocalBinder();
|
||||
|
||||
registerBus();
|
||||
MainApp.instance().getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED));
|
||||
}
|
||||
|
@ -133,17 +80,6 @@ public class DanaRExecutionService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
private void registerBus() {
|
||||
try {
|
||||
MainApp.bus().unregister(this);
|
||||
|
@ -154,49 +90,27 @@ public class DanaRExecutionService extends Service {
|
|||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(EventAppExit event) {
|
||||
if (Config.logFunctionCalls)
|
||||
log.debug("EventAppExit received");
|
||||
|
||||
public void onStatusEvent(final EventPreferenceChange pch) {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect("Application exit");
|
||||
|
||||
MainApp.instance().getApplicationContext().unregisterReceiver(receiver);
|
||||
|
||||
stopSelf();
|
||||
if (Config.logFunctionCalls)
|
||||
log.debug("EventAppExit finished");
|
||||
mSerialIOThread.disconnect("EventPreferenceChange");
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return mRfcommSocket != null && mRfcommSocket.isConnected();
|
||||
}
|
||||
|
||||
public boolean isConnecting() {
|
||||
return connectionInProgress;
|
||||
}
|
||||
|
||||
public void disconnect(String from) {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect(from);
|
||||
}
|
||||
|
||||
public void connect(String from) {
|
||||
if (danaRPump.password != -1 && danaRPump.password != SP.getInt(R.string.key_danar_password, -1)) {
|
||||
public void connect() {
|
||||
if (mDanaRPump.password != -1 && mDanaRPump.password != SP.getInt(R.string.key_danar_password, -1)) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.wrongpumppassword), R.raw.error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (connectionInProgress)
|
||||
if (mConnectionInProgress)
|
||||
return;
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
connectionInProgress = true;
|
||||
mConnectionInProgress = true;
|
||||
getBTSocketForSelectedPump();
|
||||
if (mRfcommSocket == null || mBTDevice == null) {
|
||||
connectionInProgress = false;
|
||||
mConnectionInProgress = false;
|
||||
return; // Device not found
|
||||
}
|
||||
|
||||
|
@ -217,48 +131,11 @@ public class DanaRExecutionService extends Service {
|
|||
MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTED, 0));
|
||||
}
|
||||
|
||||
connectionInProgress = false;
|
||||
mConnectionInProgress = false;
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void stopConnecting() {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect("stopConnecting");
|
||||
}
|
||||
|
||||
private void getBTSocketForSelectedPump() {
|
||||
devName = SP.getString(MainApp.sResources.getString(R.string.key_danar_bt_name), "");
|
||||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
|
||||
if (bluetoothAdapter != null) {
|
||||
Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
|
||||
|
||||
for (BluetoothDevice device : bondedDevices) {
|
||||
if (devName.equals(device.getName())) {
|
||||
mBTDevice = device;
|
||||
try {
|
||||
mRfcommSocket = mBTDevice.createRfcommSocketToServiceRecord(SPP_UUID);
|
||||
} catch (IOException e) {
|
||||
log.error("Error creating socket: ", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.nobtadapter));
|
||||
}
|
||||
if (mBTDevice == null) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.devicenotfound));
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventPreferenceChange pch) {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect("EventPreferenceChange");
|
||||
}
|
||||
|
||||
public void getPumpStatus() {
|
||||
try {
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpstatus)));
|
||||
|
@ -268,7 +145,7 @@ public class DanaRExecutionService extends Service {
|
|||
MsgStatusBolusExtended exStatusMsg = new MsgStatusBolusExtended();
|
||||
MsgCheckValue checkValue = new MsgCheckValue();
|
||||
|
||||
if (danaRPump.isNewPump) {
|
||||
if (mDanaRPump.isNewPump) {
|
||||
mSerialIOThread.sendMessage(checkValue);
|
||||
if (!checkValue.received) {
|
||||
return;
|
||||
|
@ -283,8 +160,8 @@ public class DanaRExecutionService extends Service {
|
|||
mSerialIOThread.sendMessage(exStatusMsg);
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingbolusstatus)));
|
||||
|
||||
Date now = new Date();
|
||||
if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !MainApp.getSpecificPlugin(DanaRPlugin.class).isInitialized()) {
|
||||
long now = System.currentTimeMillis();
|
||||
if (mDanaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRPlugin.class).isInitialized()) {
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpsettings)));
|
||||
mSerialIOThread.sendMessage(new MsgSettingShippingInfo());
|
||||
mSerialIOThread.sendMessage(new MsgSettingActiveProfile());
|
||||
|
@ -298,26 +175,26 @@ public class DanaRExecutionService extends Service {
|
|||
mSerialIOThread.sendMessage(new MsgSettingProfileRatiosAll());
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumptime)));
|
||||
mSerialIOThread.sendMessage(new MsgSettingPumpTime());
|
||||
long timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
long timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
log.debug("Pump time difference: " + timeDiff + " seconds");
|
||||
if (Math.abs(timeDiff) > 10) {
|
||||
mSerialIOThread.sendMessage(new MsgSetTime(new Date()));
|
||||
mSerialIOThread.sendMessage(new MsgSettingPumpTime());
|
||||
timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
log.debug("Pump time difference: " + timeDiff + " seconds");
|
||||
}
|
||||
danaRPump.lastSettingsRead = now;
|
||||
mDanaRPump.lastSettingsRead = now;
|
||||
}
|
||||
|
||||
danaRPump.lastConnection = now;
|
||||
mDanaRPump.lastConnection = now;
|
||||
MainApp.bus().post(new EventDanaRNewStatus());
|
||||
MainApp.bus().post(new EventInitializationChanged());
|
||||
NSUpload.uploadDeviceStatus();
|
||||
if (danaRPump.dailyTotalUnits > danaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) {
|
||||
log.debug("Approaching daily limit: " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits);
|
||||
if (mDanaRPump.dailyTotalUnits > mDanaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) {
|
||||
log.debug("Approaching daily limit: " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits);
|
||||
Notification reportFail = new Notification(Notification.APPROACHING_DAILY_LIMIT, MainApp.sResources.getString(R.string.approachingdailylimit), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(reportFail));
|
||||
NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits + "U");
|
||||
NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits + "U");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
|
@ -326,10 +203,10 @@ public class DanaRExecutionService extends Service {
|
|||
|
||||
public boolean tempBasal(int percent, int durationInHours) {
|
||||
if (!isConnected()) return false;
|
||||
if (danaRPump.isTempBasalInProgress) {
|
||||
if (mDanaRPump.isTempBasalInProgress) {
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal)));
|
||||
mSerialIOThread.sendMessage(new MsgSetTempBasalStop());
|
||||
waitMsec(500);
|
||||
SystemClock.sleep(500);
|
||||
}
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.settingtempbasal)));
|
||||
mSerialIOThread.sendMessage(new MsgSetTempBasalStart(percent, durationInHours));
|
||||
|
@ -365,11 +242,16 @@ public class DanaRExecutionService extends Service {
|
|||
return true;
|
||||
}
|
||||
|
||||
public boolean bolus(double amount, int carbs, final Treatment t) {
|
||||
@Override
|
||||
public PumpEnactResult loadEvents() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean bolus(double amount, int carbs, long carbtime, final Treatment t) {
|
||||
if (!isConnected()) return false;
|
||||
if (BolusProgressDialog.stopPressed) return false;
|
||||
|
||||
bolusingTreatment = t;
|
||||
mBolusingTreatment = t;
|
||||
int preferencesSpeed = SP.getInt(R.string.key_danars_bolusspeed, 0);
|
||||
MessageBase start;
|
||||
if (preferencesSpeed == 0)
|
||||
|
@ -379,7 +261,7 @@ public class DanaRExecutionService extends Service {
|
|||
MsgBolusStop stop = new MsgBolusStop(amount, t);
|
||||
|
||||
if (carbs > 0) {
|
||||
mSerialIOThread.sendMessage(new MsgSetCarbsEntry(System.currentTimeMillis(), carbs));
|
||||
mSerialIOThread.sendMessage(new MsgSetCarbsEntry(carbtime, carbs));
|
||||
}
|
||||
|
||||
MsgBolusProgress progress = new MsgBolusProgress(amount, t); // initialize static variables
|
||||
|
@ -392,20 +274,20 @@ public class DanaRExecutionService extends Service {
|
|||
return false;
|
||||
}
|
||||
while (!stop.stopped && !start.failed) {
|
||||
waitMsec(100);
|
||||
SystemClock.sleep(100);
|
||||
if ((System.currentTimeMillis() - progress.lastReceive) > 15 * 1000L) { // if i didn't receive status for more than 15 sec expecting broken comm
|
||||
stop.stopped = true;
|
||||
stop.forced = true;
|
||||
log.debug("Communication stopped");
|
||||
}
|
||||
}
|
||||
waitMsec(300);
|
||||
SystemClock.sleep(300);
|
||||
|
||||
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance();
|
||||
bolusingEvent.t = t;
|
||||
bolusingEvent.percent = 99;
|
||||
|
||||
bolusingTreatment = null;
|
||||
mBolusingTreatment = null;
|
||||
|
||||
int speed = 12;
|
||||
switch (preferencesSpeed) {
|
||||
|
@ -437,11 +319,11 @@ public class DanaRExecutionService extends Service {
|
|||
ConfigBuilderPlugin.getCommandQueue().independentConnect("bolusingInterrupted", new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (danaRPump.lastBolusTime.getTime() > System.currentTimeMillis() - 60 * 1000L) { // last bolus max 1 min old
|
||||
t.insulin = danaRPump.lastBolusAmount;
|
||||
log.debug("Used bolus amount from history: " + danaRPump.lastBolusAmount);
|
||||
if (mDanaRPump.lastBolusTime.getTime() > System.currentTimeMillis() - 60 * 1000L) { // last bolus max 1 min old
|
||||
t.insulin = mDanaRPump.lastBolusAmount;
|
||||
log.debug("Used bolus amount from history: " + mDanaRPump.lastBolusAmount);
|
||||
} else {
|
||||
log.debug("Bolus amount in history too old: " + danaRPump.lastBolusTime.toLocaleString());
|
||||
log.debug("Bolus amount in history too old: " + mDanaRPump.lastBolusTime.toLocaleString());
|
||||
}
|
||||
synchronized (o) {
|
||||
o.notify();
|
||||
|
@ -460,22 +342,6 @@ public class DanaRExecutionService extends Service {
|
|||
return true;
|
||||
}
|
||||
|
||||
public void bolusStop() {
|
||||
if (Config.logDanaBTComm)
|
||||
log.debug("bolusStop >>>>> @ " + (bolusingTreatment == null ? "" : bolusingTreatment.insulin));
|
||||
MsgBolusStop stop = new MsgBolusStop();
|
||||
stop.forced = true;
|
||||
if (isConnected()) {
|
||||
mSerialIOThread.sendMessage(stop);
|
||||
while (!stop.stopped) {
|
||||
mSerialIOThread.sendMessage(stop);
|
||||
waitMsec(200);
|
||||
}
|
||||
} else {
|
||||
stop.stopped = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean carbsEntry(int amount) {
|
||||
if (!isConnected()) return false;
|
||||
MsgSetCarbsEntry msg = new MsgSetCarbsEntry(System.currentTimeMillis(), amount);
|
||||
|
@ -483,51 +349,9 @@ public class DanaRExecutionService extends Service {
|
|||
return true;
|
||||
}
|
||||
|
||||
public PumpEnactResult loadHistory(byte type) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
if (!isConnected()) return result;
|
||||
MessageBase msg = null;
|
||||
switch (type) {
|
||||
case RecordTypes.RECORD_TYPE_ALARM:
|
||||
msg = new MsgHistoryAlarm();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_BASALHOUR:
|
||||
msg = new MsgHistoryBasalHour();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_BOLUS:
|
||||
msg = new MsgHistoryBolus();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_CARBO:
|
||||
msg = new MsgHistoryCarbo();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_DAILY:
|
||||
msg = new MsgHistoryDailyInsulin();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_ERROR:
|
||||
msg = new MsgHistoryError();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_GLUCOSE:
|
||||
msg = new MsgHistoryGlucose();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_REFILL:
|
||||
msg = new MsgHistoryRefill();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_SUSPEND:
|
||||
msg = new MsgHistorySuspend();
|
||||
break;
|
||||
}
|
||||
MsgHistoryDone done = new MsgHistoryDone();
|
||||
mSerialIOThread.sendMessage(new MsgPCCommStart());
|
||||
waitMsec(400);
|
||||
mSerialIOThread.sendMessage(msg);
|
||||
while (!done.received && mRfcommSocket.isConnected()) {
|
||||
waitMsec(100);
|
||||
}
|
||||
waitMsec(200);
|
||||
mSerialIOThread.sendMessage(new MsgPCCommStop());
|
||||
result.success = true;
|
||||
result.comment = "OK";
|
||||
return result;
|
||||
@Override
|
||||
public boolean highTempBasal(int percent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updateBasalsInPump(final Profile profile) {
|
||||
|
@ -538,13 +362,25 @@ public class DanaRExecutionService extends Service {
|
|||
mSerialIOThread.sendMessage(msgSet);
|
||||
MsgSetActivateBasalProfile msgActivate = new MsgSetActivateBasalProfile((byte) 0);
|
||||
mSerialIOThread.sendMessage(msgActivate);
|
||||
danaRPump.lastSettingsRead = new Date(0); // force read full settings
|
||||
mDanaRPump.lastSettingsRead = 0; // force read full settings
|
||||
getPumpStatus();
|
||||
MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING));
|
||||
return true;
|
||||
}
|
||||
|
||||
private void waitMsec(long msecs) {
|
||||
SystemClock.sleep(msecs);
|
||||
@Subscribe
|
||||
public void onStatusEvent(EventAppExit event) {
|
||||
if (Config.logFunctionCalls)
|
||||
log.debug("EventAppExit received");
|
||||
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect("Application exit");
|
||||
|
||||
MainApp.instance().getApplicationContext().unregisterReceiver(receiver);
|
||||
|
||||
stopSelf();
|
||||
if (Config.logFunctionCalls)
|
||||
log.debug("EventAppExit finished");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,71 +5,31 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||
import info.nightscout.androidaps.interfaces.DanaRInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.ProfileInterface;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRFragment;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.AbstractDanaRPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.services.DanaRKoreanExecutionService;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.Round;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.08.2016.
|
||||
*/
|
||||
public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(DanaRKoreanPlugin.class);
|
||||
|
||||
@Override
|
||||
public String getFragmentClass() {
|
||||
return DanaRFragment.class.getName();
|
||||
}
|
||||
|
||||
private static boolean fragmentPumpEnabled = false;
|
||||
private static boolean fragmentProfileEnabled = false;
|
||||
private static boolean fragmentPumpVisible = true;
|
||||
|
||||
private static DanaRKoreanExecutionService sExecutionService;
|
||||
|
||||
|
||||
private static DanaRPump pump = DanaRPump.getInstance();
|
||||
private boolean useExtendedBoluses = false;
|
||||
public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
|
||||
|
||||
private static DanaRKoreanPlugin plugin = null;
|
||||
|
||||
|
@ -79,9 +39,8 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
|
|||
return plugin;
|
||||
}
|
||||
|
||||
public static PumpDescription pumpDescription = new PumpDescription();
|
||||
|
||||
public DanaRKoreanPlugin() {
|
||||
log = LoggerFactory.getLogger(DanaRKoreanPlugin.class);
|
||||
useExtendedBoluses = SP.getBoolean("danar_useextended", false);
|
||||
|
||||
Context context = MainApp.instance().getApplicationContext();
|
||||
|
@ -149,83 +108,17 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
|
|||
}
|
||||
|
||||
// Plugin base interface
|
||||
@Override
|
||||
public int getType() {
|
||||
return PluginBase.PUMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return MainApp.instance().getString(R.string.danarkoreanpump);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameShort() {
|
||||
String name = MainApp.sResources.getString(R.string.danarpump_shortname);
|
||||
if (!name.trim().isEmpty()) {
|
||||
//only if translation exists
|
||||
return name;
|
||||
}
|
||||
// use long name as fallback
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int type) {
|
||||
if (type == PluginBase.PROFILE) return fragmentProfileEnabled && fragmentPumpEnabled;
|
||||
else if (type == PluginBase.PUMP) return fragmentPumpEnabled;
|
||||
else if (type == PluginBase.CONSTRAINTS) return fragmentPumpEnabled;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisibleInTabs(int type) {
|
||||
if (type == PluginBase.PROFILE || type == PluginBase.CONSTRAINTS) return false;
|
||||
else if (type == PluginBase.PUMP) return fragmentPumpVisible;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeHidden(int type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFragment() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showInList(int type) {
|
||||
return type == PUMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
||||
if (type == PluginBase.PROFILE)
|
||||
fragmentProfileEnabled = fragmentEnabled;
|
||||
else if (type == PluginBase.PUMP)
|
||||
fragmentPumpEnabled = fragmentEnabled;
|
||||
// if pump profile was enabled need to switch to another too
|
||||
if (type == PluginBase.PUMP && !fragmentEnabled && fragmentProfileEnabled) {
|
||||
setFragmentEnabled(PluginBase.PROFILE, false);
|
||||
setFragmentVisible(PluginBase.PROFILE, false);
|
||||
NSProfilePlugin.getPlugin().setFragmentEnabled(PluginBase.PROFILE, true);
|
||||
NSProfilePlugin.getPlugin().setFragmentVisible(PluginBase.PROFILE, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
||||
if (type == PluginBase.PUMP)
|
||||
fragmentPumpVisible = fragmentVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferencesId() {
|
||||
return R.xml.pref_danarkorean;
|
||||
}
|
||||
|
||||
// Pump interface
|
||||
@Override
|
||||
public boolean isFakingTempsByExtendedBoluses() {
|
||||
return useExtendedBoluses;
|
||||
|
@ -233,82 +126,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
|
|||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return pump.lastConnection.getTime() > 0 && pump.maxBasal > 0 && !pump.isConfigUD && !pump.isEasyModeEnabled && pump.isExtendedBolusEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuspended() {
|
||||
return pump.pumpSuspended;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBusy() {
|
||||
if (sExecutionService == null) return false;
|
||||
return sExecutionService.isConnected() || sExecutionService.isConnecting();
|
||||
}
|
||||
|
||||
// Pump interface
|
||||
@Override
|
||||
public PumpEnactResult setNewBasalProfile(Profile profile) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
|
||||
if (sExecutionService == null) {
|
||||
log.error("setNewBasalProfile sExecutionService is null");
|
||||
result.comment = "setNewBasalProfile sExecutionService is null";
|
||||
return result;
|
||||
}
|
||||
if (!isInitialized()) {
|
||||
log.error("setNewBasalProfile not initialized");
|
||||
Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
result.comment = MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet);
|
||||
return result;
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
|
||||
}
|
||||
if (!sExecutionService.updateBasalsInPump(profile)) {
|
||||
Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.sResources.getString(R.string.failedupdatebasalprofile), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
result.comment = MainApp.sResources.getString(R.string.failedupdatebasalprofile);
|
||||
return result;
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE));
|
||||
result.success = true;
|
||||
result.enacted = true;
|
||||
result.comment = "OK";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThisProfileSet(Profile profile) {
|
||||
if (!isInitialized())
|
||||
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
|
||||
if (pump.pumpProfiles == null)
|
||||
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
|
||||
int basalValues = pump.basal48Enable ? 48 : 24;
|
||||
int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60;
|
||||
for (int h = 0; h < basalValues; h++) {
|
||||
Double pumpValue = pump.pumpProfiles[pump.activeProfile][h];
|
||||
Double profileValue = profile.getBasal((Integer) (h * basalIncrement));
|
||||
if (profileValue == null) return true;
|
||||
if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) {
|
||||
log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date lastDataTime() {
|
||||
return pump.lastConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBaseBasalRate() {
|
||||
return pump.currentBasal;
|
||||
return pump.lastConnection > 0 && pump.maxBasal > 0 && !pump.isConfigUD && !pump.isEasyModeEnabled && pump.isExtendedBolusEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -318,7 +136,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
|
|||
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
|
||||
Treatment t = new Treatment();
|
||||
boolean connectionOK = false;
|
||||
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, t);
|
||||
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t);
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
result.success = connectionOK;
|
||||
result.bolusDelivered = t.insulin;
|
||||
|
@ -341,15 +159,6 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopBolusDelivering() {
|
||||
if (sExecutionService == null) {
|
||||
log.error("stopBolusDelivering sExecutionService is null");
|
||||
return;
|
||||
}
|
||||
sExecutionService.bolusStop();
|
||||
}
|
||||
|
||||
// This is called from APS
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) {
|
||||
|
@ -502,100 +311,6 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
|
||||
percent = configBuilderPlugin.applyBasalConstraints(percent);
|
||||
if (percent < 0) {
|
||||
result.isTempCancel = false;
|
||||
result.enacted = false;
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
|
||||
log.error("setTempBasalPercent: Invalid input");
|
||||
return result;
|
||||
}
|
||||
if (percent > getPumpDescription().maxTempPercent)
|
||||
percent = getPumpDescription().maxTempPercent;
|
||||
TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (runningTB != null && runningTB.percentRate == percent && enforceNew) {
|
||||
result.enacted = false;
|
||||
result.success = true;
|
||||
result.isTempCancel = false;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.duration = pump.tempBasalRemainingMin;
|
||||
result.percent = pump.tempBasalPercent;
|
||||
result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory();
|
||||
result.isPercent = true;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setTempBasalPercent: Correct value already set");
|
||||
return result;
|
||||
}
|
||||
int durationInHours = Math.max(durationInMinutes / 60, 1);
|
||||
boolean connectionOK = sExecutionService.tempBasal(percent, durationInHours);
|
||||
if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) {
|
||||
result.enacted = true;
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.isTempCancel = false;
|
||||
result.duration = pump.tempBasalRemainingMin;
|
||||
result.percent = pump.tempBasalPercent;
|
||||
result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory();
|
||||
result.isPercent = true;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setTempBasalPercent: OK");
|
||||
return result;
|
||||
}
|
||||
result.enacted = false;
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
|
||||
log.error("setTempBasalPercent: Failed to set temp basal");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
|
||||
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
|
||||
insulin = configBuilderPlugin.applyBolusConstraints(insulin);
|
||||
// needs to be rounded
|
||||
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
|
||||
insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep);
|
||||
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) {
|
||||
result.enacted = false;
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.duration = pump.extendedBolusRemainingMinutes;
|
||||
result.absolute = pump.extendedBolusAbsoluteRate;
|
||||
result.isPercent = false;
|
||||
result.isTempCancel = false;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin);
|
||||
return result;
|
||||
}
|
||||
boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours);
|
||||
if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) {
|
||||
result.enacted = true;
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.isTempCancel = false;
|
||||
result.duration = pump.extendedBolusRemainingMinutes;
|
||||
result.absolute = pump.extendedBolusAbsoluteRate;
|
||||
result.bolusDelivered = pump.extendedBolusAmount;
|
||||
result.isPercent = false;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setExtendedBolus: OK");
|
||||
return result;
|
||||
}
|
||||
result.enacted = false;
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
|
||||
log.error("setExtendedBolus: Failed to extended bolus");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult cancelTempBasal(boolean force) {
|
||||
if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress())
|
||||
|
@ -636,257 +351,8 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult cancelExtendedBolus() {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (runningEB != null) {
|
||||
sExecutionService.extendedBolusStop();
|
||||
result.enacted = true;
|
||||
result.isTempCancel = true;
|
||||
}
|
||||
if (!pump.isExtendedInProgress) {
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
if (Config.logPumpActions)
|
||||
log.debug("cancelExtendedBolus: OK");
|
||||
return result;
|
||||
} else {
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
|
||||
log.error("cancelExtendedBolus: Failed to cancel extended bolus");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(String from) {
|
||||
if (sExecutionService != null) {
|
||||
sExecutionService.connect(from);
|
||||
pumpDescription.basalStep = pump.basalStep;
|
||||
pumpDescription.bolusStep = pump.bolusStep;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return sExecutionService != null && sExecutionService.isConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnecting() {
|
||||
return sExecutionService != null && sExecutionService.isConnecting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String from) {
|
||||
if (sExecutionService != null) sExecutionService.disconnect(from);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopConnecting() {
|
||||
if (sExecutionService != null) sExecutionService.stopConnecting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPumpStatus() {
|
||||
if (sExecutionService != null) sExecutionService.getPumpStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getJSONStatus() {
|
||||
if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) {
|
||||
return null;
|
||||
}
|
||||
JSONObject pumpjson = new JSONObject();
|
||||
JSONObject battery = new JSONObject();
|
||||
JSONObject status = new JSONObject();
|
||||
JSONObject extended = new JSONObject();
|
||||
try {
|
||||
battery.put("percent", pump.batteryRemaining);
|
||||
status.put("status", pump.pumpSuspended ? "suspended" : "normal");
|
||||
status.put("timestamp", DateUtil.toISOString(pump.lastConnection));
|
||||
extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION);
|
||||
extended.put("PumpIOB", pump.iob);
|
||||
if (pump.lastBolusTime.getTime() != 0) {
|
||||
extended.put("LastBolus", pump.lastBolusTime.toLocaleString());
|
||||
extended.put("LastBolusAmount", pump.lastBolusAmount);
|
||||
}
|
||||
TemporaryBasal tb = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (tb != null) {
|
||||
extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis()));
|
||||
extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date));
|
||||
extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes());
|
||||
}
|
||||
ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (eb != null) {
|
||||
extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate());
|
||||
extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date));
|
||||
extended.put("ExtendedBolusRemaining", eb.getPlannedRemainingMinutes());
|
||||
}
|
||||
extended.put("BaseBasalRate", getBaseBasalRate());
|
||||
try {
|
||||
extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
pumpjson.put("battery", battery);
|
||||
pumpjson.put("status", status);
|
||||
pumpjson.put("extended", extended);
|
||||
pumpjson.put("reservoir", (int) pump.reservoirRemainingUnits);
|
||||
pumpjson.put("clock", DateUtil.toISOString(new Date()));
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return pumpjson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceID() {
|
||||
return pump.serialNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpDescription getPumpDescription() {
|
||||
return pumpDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* DanaR interface
|
||||
*/
|
||||
|
||||
@Override
|
||||
public PumpEnactResult loadHistory(byte type) {
|
||||
return sExecutionService.loadHistory(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult loadEvents() {
|
||||
return null; // no history, not needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Constraint interface
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isLoopEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosedModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutosensModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAMAModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSMBModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Double applyBasalConstraints(Double absoluteRate) {
|
||||
double origAbsoluteRate = absoluteRate;
|
||||
if (pump != null) {
|
||||
if (absoluteRate > pump.maxBasal) {
|
||||
absoluteRate = pump.maxBasal;
|
||||
if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit)
|
||||
log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h");
|
||||
}
|
||||
}
|
||||
return absoluteRate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Integer applyBasalConstraints(Integer percentRate) {
|
||||
Integer origPercentRate = percentRate;
|
||||
if (percentRate < 0) percentRate = 0;
|
||||
if (percentRate > getPumpDescription().maxTempPercent)
|
||||
percentRate = getPumpDescription().maxTempPercent;
|
||||
if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
||||
log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%");
|
||||
return percentRate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Double applyBolusConstraints(Double insulin) {
|
||||
double origInsulin = insulin;
|
||||
if (pump != null) {
|
||||
if (insulin > pump.maxBolus) {
|
||||
insulin = pump.maxBolus;
|
||||
if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit)
|
||||
log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U");
|
||||
}
|
||||
}
|
||||
return insulin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer applyCarbsConstraints(Integer carbs) {
|
||||
return carbs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double applyMaxIOBConstraints(Double maxIob) {
|
||||
return maxIob;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ProfileStore getProfile() {
|
||||
if (pump.lastSettingsRead.getTime() == 0)
|
||||
return null; // no info now
|
||||
return pump.createConvertedProfile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnits() {
|
||||
return pump.getUnits();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProfileName() {
|
||||
return pump.createConvertedProfileName();
|
||||
}
|
||||
|
||||
// Reply for sms communicator
|
||||
public String shortStatus(boolean veryShort) {
|
||||
String ret = "";
|
||||
if (pump.lastConnection.getTime() != 0) {
|
||||
Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime();
|
||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
||||
ret += "LastConn: " + agoMin + " minago\n";
|
||||
}
|
||||
if (pump.lastBolusTime.getTime() != 0) {
|
||||
ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n";
|
||||
}
|
||||
if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) {
|
||||
ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n";
|
||||
}
|
||||
if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n";
|
||||
}
|
||||
if (!veryShort) {
|
||||
ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n";
|
||||
}
|
||||
ret += "IOB: " + pump.iob + "U\n";
|
||||
ret += "Reserv: " + DecimalFormatter.to0Decimal(pump.reservoirRemainingUnits) + "U\n";
|
||||
ret += "Batt: " + pump.batteryRemaining + "\n";
|
||||
return ret;
|
||||
}
|
||||
// TODO: daily total constraint
|
||||
|
||||
}
|
||||
|
|
|
@ -13,13 +13,14 @@ import java.io.OutputStream;
|
|||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractSerialIOThread;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.comm.MessageHashTable_k;
|
||||
import info.nightscout.utils.CRC;
|
||||
|
||||
/**
|
||||
* Created by mike on 17.07.2016.
|
||||
*/
|
||||
public class SerialIOThread extends Thread {
|
||||
public class SerialIOThread extends AbstractSerialIOThread {
|
||||
private static Logger log = LoggerFactory.getLogger(SerialIOThread.class);
|
||||
|
||||
private InputStream mInputStream = null;
|
||||
|
@ -29,10 +30,10 @@ public class SerialIOThread extends Thread {
|
|||
private boolean mKeepRunning = true;
|
||||
private byte[] mReadBuff = new byte[0];
|
||||
|
||||
MessageBase processedMessage;
|
||||
private MessageBase processedMessage;
|
||||
|
||||
public SerialIOThread(BluetoothSocket rfcommSocket) {
|
||||
super(SerialIOThread.class.toString());
|
||||
super();
|
||||
|
||||
mRfCommSocket = rfcommSocket;
|
||||
try {
|
||||
|
@ -138,6 +139,7 @@ public class SerialIOThread extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void sendMessage(MessageBase message) {
|
||||
if (!mRfCommSocket.isConnected()) {
|
||||
log.error("Socket not connected on sendMessage");
|
||||
|
@ -173,6 +175,7 @@ public class SerialIOThread extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String reason) {
|
||||
mKeepRunning = false;
|
||||
try {
|
||||
|
|
|
@ -37,7 +37,7 @@ public class MsgInitConnStatusTime_k extends MessageBase {
|
|||
MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginBase.PUMP, false);
|
||||
MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentEnabled(PluginBase.PUMP, true);
|
||||
MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentVisible(PluginBase.PUMP, true);
|
||||
DanaRPump.getInstance().lastConnection = new Date(0); // mark not initialized
|
||||
DanaRPump.getInstance().lastConnection = 0; // mark not initialized
|
||||
|
||||
//If profile coming from pump, switch it as well
|
||||
if (MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isEnabled(PluginBase.PROFILE)) {
|
||||
|
|
|
@ -24,7 +24,7 @@ public class MsgSettingBasal_k extends MessageBase {
|
|||
pump.pumpProfiles[pump.activeProfile] = new double[24];
|
||||
for (int index = 0; index < 24; index++) {
|
||||
int basal = intFromBuff(bytes, 2 * index, 2);
|
||||
if (basal < DanaRKoreanPlugin.pumpDescription.basalMinimumRate) basal = 0;
|
||||
if (basal < DanaRKoreanPlugin.getPlugin().pumpDescription.basalMinimumRate) basal = 0;
|
||||
pump.pumpProfiles[pump.activeProfile][index] = basal / 100d;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,58 +1,36 @@
|
|||
package info.nightscout.androidaps.plugins.PumpDanaRKorean.services;
|
||||
|
||||
import android.app.Service;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothSocket;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventInitializationChanged;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.events.EventPumpStatusChanged;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusProgress;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStart;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStop;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryAlarm;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBasalHour;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryBolus;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryCarbo;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDailyInsulin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryDone;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryError;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryGlucose;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryRefill;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistorySuspend;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStart;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStop;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetCarbsEntry;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetExtendedBolusStart;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetExtendedBolusStop;
|
||||
|
@ -68,56 +46,23 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingPumpTime;
|
|||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingShippingInfo;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBolusExtended;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusTempBasal;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractDanaRExecutionService;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.SerialIOThread;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.comm.MsgCheckValue_k;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.comm.MsgSettingBasal_k;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.comm.MsgStatusBasic_k;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
public class DanaRKoreanExecutionService extends Service {
|
||||
private static Logger log = LoggerFactory.getLogger(DanaRKoreanExecutionService.class);
|
||||
|
||||
private String devName;
|
||||
|
||||
private SerialIOThread mSerialIOThread;
|
||||
private BluetoothSocket mRfcommSocket;
|
||||
private BluetoothDevice mBTDevice;
|
||||
|
||||
private IBinder mBinder = new LocalBinder();
|
||||
|
||||
private DanaRPump danaRPump = DanaRPump.getInstance();
|
||||
private Treatment bolusingTreatment = null;
|
||||
|
||||
private static Boolean connectionInProgress = false;
|
||||
|
||||
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
|
||||
|
||||
private BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
String action = intent.getAction();
|
||||
if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
|
||||
log.debug("Device was disconnected " + device.getName());//Device was disconnected
|
||||
if (mBTDevice != null && mBTDevice.getName() != null && mBTDevice.getName().equals(device.getName())) {
|
||||
if (mSerialIOThread != null) {
|
||||
mSerialIOThread.disconnect("BT disconnection broadcast");
|
||||
}
|
||||
MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService {
|
||||
|
||||
public DanaRKoreanExecutionService() {
|
||||
log = LoggerFactory.getLogger(DanaRKoreanExecutionService.class);
|
||||
mBinder = new LocalBinder();
|
||||
|
||||
registerBus();
|
||||
MainApp.instance().getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED));
|
||||
}
|
||||
|
@ -128,17 +73,6 @@ public class DanaRKoreanExecutionService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
private void registerBus() {
|
||||
try {
|
||||
MainApp.bus().unregister(this);
|
||||
|
@ -163,35 +97,28 @@ public class DanaRKoreanExecutionService extends Service {
|
|||
log.debug("EventAppExit finished");
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return mRfcommSocket != null && mRfcommSocket.isConnected();
|
||||
}
|
||||
|
||||
public boolean isConnecting() {
|
||||
return connectionInProgress;
|
||||
}
|
||||
|
||||
public void disconnect(String from) {
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventPreferenceChange pch) {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect(from);
|
||||
mSerialIOThread.disconnect("EventPreferenceChange");
|
||||
}
|
||||
|
||||
public void connect(String from) {
|
||||
if (danaRPump.password != -1 && danaRPump.password != SP.getInt(R.string.key_danar_password, -1)) {
|
||||
public void connect() {
|
||||
if (mDanaRPump.password != -1 && mDanaRPump.password != SP.getInt(R.string.key_danar_password, -1)) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.wrongpumppassword), R.raw.error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (connectionInProgress)
|
||||
if (mConnectionInProgress)
|
||||
return;
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
connectionInProgress = true;
|
||||
mConnectionInProgress = true;
|
||||
getBTSocketForSelectedPump();
|
||||
if (mRfcommSocket == null || mBTDevice == null) {
|
||||
connectionInProgress = false;
|
||||
mConnectionInProgress = false;
|
||||
return; // Device not found
|
||||
}
|
||||
|
||||
|
@ -212,48 +139,11 @@ public class DanaRKoreanExecutionService extends Service {
|
|||
MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTED, 0));
|
||||
}
|
||||
|
||||
connectionInProgress = false;
|
||||
mConnectionInProgress = false;
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void stopConnecting() {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect("stopConnecting");
|
||||
}
|
||||
|
||||
private void getBTSocketForSelectedPump() {
|
||||
devName = SP.getString(MainApp.sResources.getString(R.string.key_danar_bt_name), "");
|
||||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
|
||||
if (bluetoothAdapter != null) {
|
||||
Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
|
||||
|
||||
for (BluetoothDevice device : bondedDevices) {
|
||||
if (devName.equals(device.getName())) {
|
||||
mBTDevice = device;
|
||||
try {
|
||||
mRfcommSocket = mBTDevice.createRfcommSocketToServiceRecord(SPP_UUID);
|
||||
} catch (IOException e) {
|
||||
log.error("Error creating socket: ", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.nobtadapter));
|
||||
}
|
||||
if (mBTDevice == null) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.devicenotfound));
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventPreferenceChange pch) {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect("EventPreferenceChange");
|
||||
}
|
||||
|
||||
public void getPumpStatus() {
|
||||
try {
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpstatus)));
|
||||
|
@ -263,7 +153,7 @@ public class DanaRKoreanExecutionService extends Service {
|
|||
MsgStatusBolusExtended exStatusMsg = new MsgStatusBolusExtended();
|
||||
MsgCheckValue_k checkValue = new MsgCheckValue_k();
|
||||
|
||||
if (danaRPump.isNewPump) {
|
||||
if (mDanaRPump.isNewPump) {
|
||||
mSerialIOThread.sendMessage(checkValue);
|
||||
if (!checkValue.received) {
|
||||
return;
|
||||
|
@ -278,8 +168,8 @@ public class DanaRKoreanExecutionService extends Service {
|
|||
mSerialIOThread.sendMessage(exStatusMsg);
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingbolusstatus)));
|
||||
|
||||
Date now = new Date();
|
||||
if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isInitialized()) {
|
||||
long now = System.currentTimeMillis();
|
||||
if (mDanaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isInitialized()) {
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpsettings)));
|
||||
mSerialIOThread.sendMessage(new MsgSettingShippingInfo());
|
||||
mSerialIOThread.sendMessage(new MsgSettingMeal());
|
||||
|
@ -290,39 +180,38 @@ public class DanaRKoreanExecutionService extends Service {
|
|||
mSerialIOThread.sendMessage(new MsgSettingProfileRatios());
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumptime)));
|
||||
mSerialIOThread.sendMessage(new MsgSettingPumpTime());
|
||||
long timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
long timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
log.debug("Pump time difference: " + timeDiff + " seconds");
|
||||
if (Math.abs(timeDiff) > 10) {
|
||||
mSerialIOThread.sendMessage(new MsgSetTime(new Date()));
|
||||
mSerialIOThread.sendMessage(new MsgSettingPumpTime());
|
||||
timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
log.debug("Pump time difference: " + timeDiff + " seconds");
|
||||
}
|
||||
danaRPump.lastSettingsRead = now;
|
||||
mDanaRPump.lastSettingsRead = now;
|
||||
}
|
||||
|
||||
danaRPump.lastConnection = now;
|
||||
mDanaRPump.lastConnection = now;
|
||||
MainApp.bus().post(new EventDanaRNewStatus());
|
||||
MainApp.bus().post(new EventInitializationChanged());
|
||||
NSUpload.uploadDeviceStatus();
|
||||
if (danaRPump.dailyTotalUnits > danaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) {
|
||||
log.debug("Approaching daily limit: " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits);
|
||||
if (mDanaRPump.dailyTotalUnits > mDanaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) {
|
||||
log.debug("Approaching daily limit: " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits);
|
||||
Notification reportFail = new Notification(Notification.APPROACHING_DAILY_LIMIT, MainApp.sResources.getString(R.string.approachingdailylimit), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(reportFail));
|
||||
NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits + "U");
|
||||
NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits + "U");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public boolean tempBasal(int percent, int durationInHours) {
|
||||
if (!isConnected()) return false;
|
||||
if (danaRPump.isTempBasalInProgress) {
|
||||
if (mDanaRPump.isTempBasalInProgress) {
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal)));
|
||||
mSerialIOThread.sendMessage(new MsgSetTempBasalStop());
|
||||
waitMsec(500);
|
||||
SystemClock.sleep(500);
|
||||
}
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.settingtempbasal)));
|
||||
mSerialIOThread.sendMessage(new MsgSetTempBasalStart(percent, durationInHours));
|
||||
|
@ -358,16 +247,21 @@ public class DanaRKoreanExecutionService extends Service {
|
|||
return true;
|
||||
}
|
||||
|
||||
public boolean bolus(double amount, int carbs, final Treatment t) {
|
||||
@Override
|
||||
public PumpEnactResult loadEvents() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean bolus(double amount, int carbs, long carbtime, final Treatment t) {
|
||||
if (!isConnected()) return false;
|
||||
if (BolusProgressDialog.stopPressed) return false;
|
||||
|
||||
bolusingTreatment = t;
|
||||
mBolusingTreatment = t;
|
||||
MsgBolusStart start = new MsgBolusStart(amount);
|
||||
MsgBolusStop stop = new MsgBolusStop(amount, t);
|
||||
|
||||
if (carbs > 0) {
|
||||
mSerialIOThread.sendMessage(new MsgSetCarbsEntry(System.currentTimeMillis(), carbs));
|
||||
mSerialIOThread.sendMessage(new MsgSetCarbsEntry(carbtime, carbs));
|
||||
}
|
||||
|
||||
MsgBolusProgress progress = new MsgBolusProgress(amount, t); // initialize static variables
|
||||
|
@ -380,37 +274,21 @@ public class DanaRKoreanExecutionService extends Service {
|
|||
return false;
|
||||
}
|
||||
while (!stop.stopped && !start.failed) {
|
||||
waitMsec(100);
|
||||
SystemClock.sleep(100);
|
||||
if ((System.currentTimeMillis() - progress.lastReceive) > 15 * 1000L) { // if i didn't receive status for more than 15 sec expecting broken comm
|
||||
stop.stopped = true;
|
||||
stop.forced = true;
|
||||
log.debug("Communication stopped");
|
||||
}
|
||||
}
|
||||
waitMsec(300);
|
||||
SystemClock.sleep(300);
|
||||
|
||||
bolusingTreatment = null;
|
||||
mBolusingTreatment = null;
|
||||
ConfigBuilderPlugin.getCommandQueue().readStatus("bolusOK", null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void bolusStop() {
|
||||
if (Config.logDanaBTComm)
|
||||
log.debug("bolusStop >>>>> @ " + (bolusingTreatment == null ? "" : bolusingTreatment.insulin));
|
||||
MsgBolusStop stop = new MsgBolusStop();
|
||||
stop.forced = true;
|
||||
if (isConnected()) {
|
||||
mSerialIOThread.sendMessage(stop);
|
||||
while (!stop.stopped) {
|
||||
mSerialIOThread.sendMessage(stop);
|
||||
waitMsec(200);
|
||||
}
|
||||
} else {
|
||||
stop.stopped = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean carbsEntry(int amount) {
|
||||
if (!isConnected()) return false;
|
||||
MsgSetCarbsEntry msg = new MsgSetCarbsEntry(System.currentTimeMillis(), amount);
|
||||
|
@ -418,51 +296,9 @@ public class DanaRKoreanExecutionService extends Service {
|
|||
return true;
|
||||
}
|
||||
|
||||
public PumpEnactResult loadHistory(byte type) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
if (!isConnected()) return result;
|
||||
MessageBase msg = null;
|
||||
switch (type) {
|
||||
case RecordTypes.RECORD_TYPE_ALARM:
|
||||
msg = new MsgHistoryAlarm();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_BASALHOUR:
|
||||
msg = new MsgHistoryBasalHour();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_BOLUS:
|
||||
msg = new MsgHistoryBolus();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_CARBO:
|
||||
msg = new MsgHistoryCarbo();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_DAILY:
|
||||
msg = new MsgHistoryDailyInsulin();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_ERROR:
|
||||
msg = new MsgHistoryError();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_GLUCOSE:
|
||||
msg = new MsgHistoryGlucose();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_REFILL:
|
||||
msg = new MsgHistoryRefill();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_SUSPEND:
|
||||
msg = new MsgHistorySuspend();
|
||||
break;
|
||||
}
|
||||
MsgHistoryDone done = new MsgHistoryDone();
|
||||
mSerialIOThread.sendMessage(new MsgPCCommStart());
|
||||
waitMsec(400);
|
||||
mSerialIOThread.sendMessage(msg);
|
||||
while (!done.received && mRfcommSocket.isConnected()) {
|
||||
waitMsec(100);
|
||||
}
|
||||
waitMsec(200);
|
||||
mSerialIOThread.sendMessage(new MsgPCCommStop());
|
||||
result.success = true;
|
||||
result.comment = "OK";
|
||||
return result;
|
||||
@Override
|
||||
public boolean highTempBasal(int percent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updateBasalsInPump(final Profile profile) {
|
||||
|
@ -471,13 +307,10 @@ public class DanaRKoreanExecutionService extends Service {
|
|||
double[] basal = DanaRPump.buildDanaRProfileRecord(profile);
|
||||
MsgSetSingleBasalProfile msgSet = new MsgSetSingleBasalProfile(basal);
|
||||
mSerialIOThread.sendMessage(msgSet);
|
||||
danaRPump.lastSettingsRead = new Date(0); // force read full settings
|
||||
mDanaRPump.lastSettingsRead = 0; // force read full settings
|
||||
getPumpStatus();
|
||||
MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING));
|
||||
return true;
|
||||
}
|
||||
|
||||
private void waitMsec(long msecs) {
|
||||
SystemClock.sleep(msecs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -348,7 +348,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
@Nullable
|
||||
@Override
|
||||
public ProfileStore getProfile() {
|
||||
if (pump.lastSettingsRead.getTime() == 0)
|
||||
if (pump.lastSettingsRead == 0)
|
||||
return null; // no info now
|
||||
return pump.createConvertedProfile();
|
||||
}
|
||||
|
@ -367,7 +367,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return pump.lastConnection.getTime() > 0 && pump.maxBasal > 0;
|
||||
return pump.lastConnection > 0 && pump.maxBasal > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -438,7 +438,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
|
||||
@Override
|
||||
public Date lastDataTime() {
|
||||
return pump.lastConnection;
|
||||
return new Date(pump.lastConnection);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -753,7 +753,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
|
||||
@Override
|
||||
public JSONObject getJSONStatus() {
|
||||
if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) {
|
||||
if (pump.lastConnection + 5 * 60 * 1000L < System.currentTimeMillis()) {
|
||||
return null;
|
||||
}
|
||||
JSONObject pumpjson = new JSONObject();
|
||||
|
@ -812,8 +812,8 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
@Override
|
||||
public String shortStatus(boolean veryShort) {
|
||||
String ret = "";
|
||||
if (pump.lastConnection.getTime() != 0) {
|
||||
Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime();
|
||||
if (pump.lastConnection != 0) {
|
||||
Long agoMsec = System.currentTimeMillis() - pump.lastConnection;
|
||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
||||
ret += "LastConn: " + agoMin + " minago\n";
|
||||
}
|
||||
|
|
|
@ -131,8 +131,8 @@ public class DanaRSService extends Service {
|
|||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingtempbasalstatus)));
|
||||
bleComm.sendMessage(new DanaRS_Packet_Basal_Get_Temporary_Basal_State());
|
||||
|
||||
Date now = new Date();
|
||||
if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !MainApp.getSpecificPlugin(DanaRSPlugin.class).isInitialized()) {
|
||||
long now = System.currentTimeMillis();
|
||||
if (danaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRSPlugin.class).isInitialized()) {
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpsettings)));
|
||||
bleComm.sendMessage(new DanaRS_Packet_General_Get_Shipping_Information()); // serial no
|
||||
bleComm.sendMessage(new DanaRS_Packet_General_Get_Pump_Check()); // firmware
|
||||
|
@ -357,7 +357,7 @@ public class DanaRSService extends Service {
|
|||
bleComm.sendMessage(msgSet);
|
||||
DanaRS_Packet_Basal_Set_Profile_Number msgActivate = new DanaRS_Packet_Basal_Set_Profile_Number(0);
|
||||
bleComm.sendMessage(msgActivate);
|
||||
danaRPump.lastSettingsRead = new Date(0); // force read full settings
|
||||
danaRPump.lastSettingsRead = 0; // force read full settings
|
||||
getPumpStatus();
|
||||
MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING));
|
||||
return true;
|
||||
|
|
|
@ -5,68 +5,31 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||
import info.nightscout.androidaps.interfaces.DanaRInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.ProfileInterface;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRFragment;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.AbstractDanaRPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.services.DanaRv2ExecutionService;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.Round;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.08.2016.
|
||||
*/
|
||||
public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(DanaRv2Plugin.class);
|
||||
|
||||
@Override
|
||||
public String getFragmentClass() {
|
||||
return DanaRFragment.class.getName();
|
||||
}
|
||||
|
||||
private static boolean fragmentPumpEnabled = false;
|
||||
private static boolean fragmentProfileEnabled = false;
|
||||
private static boolean fragmentPumpVisible = true;
|
||||
|
||||
private static DanaRv2ExecutionService sExecutionService;
|
||||
|
||||
public class DanaRv2Plugin extends AbstractDanaRPlugin {
|
||||
|
||||
private static DanaRv2Plugin plugin = null;
|
||||
|
||||
|
@ -76,11 +39,10 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
return plugin;
|
||||
}
|
||||
|
||||
private static DanaRPump pump = DanaRPump.getInstance();
|
||||
|
||||
private static PumpDescription pumpDescription = new PumpDescription();
|
||||
|
||||
private DanaRv2Plugin() {
|
||||
log = LoggerFactory.getLogger(DanaRv2Plugin.class);
|
||||
useExtendedBoluses = false;
|
||||
|
||||
Context context = MainApp.instance().getApplicationContext();
|
||||
Intent intent = new Intent(context, DanaRv2ExecutionService.class);
|
||||
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||
|
@ -134,78 +96,11 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
}
|
||||
|
||||
// Plugin base interface
|
||||
@Override
|
||||
public int getType() {
|
||||
return PluginBase.PUMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return MainApp.instance().getString(R.string.danarv2pump);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameShort() {
|
||||
String name = MainApp.sResources.getString(R.string.danarpump_shortname);
|
||||
if (!name.trim().isEmpty()) {
|
||||
//only if translation exists
|
||||
return name;
|
||||
}
|
||||
// use long name as fallback
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int type) {
|
||||
if (type == PluginBase.PROFILE) return fragmentProfileEnabled && fragmentPumpEnabled;
|
||||
else if (type == PluginBase.PUMP) return fragmentPumpEnabled;
|
||||
else if (type == PluginBase.CONSTRAINTS) return fragmentPumpEnabled;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisibleInTabs(int type) {
|
||||
if (type == PluginBase.PROFILE || type == PluginBase.CONSTRAINTS) return false;
|
||||
else if (type == PluginBase.PUMP) return fragmentPumpVisible;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeHidden(int type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFragment() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showInList(int type) {
|
||||
return type == PUMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
||||
if (type == PluginBase.PROFILE)
|
||||
fragmentProfileEnabled = fragmentEnabled;
|
||||
else if (type == PluginBase.PUMP)
|
||||
fragmentPumpEnabled = fragmentEnabled;
|
||||
// if pump profile was enabled need to switch to another too
|
||||
if (type == PluginBase.PUMP && !fragmentEnabled && fragmentProfileEnabled) {
|
||||
setFragmentEnabled(PluginBase.PROFILE, false);
|
||||
setFragmentVisible(PluginBase.PROFILE, false);
|
||||
NSProfilePlugin.getPlugin().setFragmentEnabled(PluginBase.PROFILE, true);
|
||||
NSProfilePlugin.getPlugin().setFragmentVisible(PluginBase.PROFILE, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
||||
if (type == PluginBase.PUMP)
|
||||
fragmentPumpVisible = fragmentVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferencesId() {
|
||||
return R.xml.pref_danarv2;
|
||||
|
@ -218,86 +113,10 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return pump.lastConnection.getTime() > 0 && pump.maxBasal > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuspended() {
|
||||
return pump.pumpSuspended;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBusy() {
|
||||
if (sExecutionService == null) return false;
|
||||
return sExecutionService.isConnected() || sExecutionService.isConnecting();
|
||||
return pump.lastConnection > 0 && pump.maxBasal > 0;
|
||||
}
|
||||
|
||||
// Pump interface
|
||||
@Override
|
||||
public PumpEnactResult setNewBasalProfile(Profile profile) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
|
||||
if (sExecutionService == null) {
|
||||
log.error("setNewBasalProfile sExecutionService is null");
|
||||
result.comment = "setNewBasalProfile sExecutionService is null";
|
||||
return result;
|
||||
}
|
||||
if (!isInitialized()) {
|
||||
log.error("setNewBasalProfile not initialized");
|
||||
Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
result.comment = MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet);
|
||||
return result;
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
|
||||
}
|
||||
if (!sExecutionService.updateBasalsInPump(profile)) {
|
||||
Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.sResources.getString(R.string.failedupdatebasalprofile), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
result.comment = MainApp.sResources.getString(R.string.failedupdatebasalprofile);
|
||||
return result;
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE));
|
||||
Notification notification = new Notification(Notification.PROFILE_SET_OK, MainApp.sResources.getString(R.string.profile_set_ok), Notification.INFO, 60);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
result.success = true;
|
||||
result.enacted = true;
|
||||
result.comment = "OK";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThisProfileSet(Profile profile) {
|
||||
if (!isInitialized())
|
||||
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
|
||||
if (pump.pumpProfiles == null)
|
||||
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
|
||||
int basalValues = pump.basal48Enable ? 48 : 24;
|
||||
int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60;
|
||||
for (int h = 0; h < basalValues; h++) {
|
||||
Double pumpValue = pump.pumpProfiles[pump.activeProfile][h];
|
||||
Double profileValue = profile.getBasal((Integer) (h * basalIncrement));
|
||||
if (profileValue == null) return true;
|
||||
if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) {
|
||||
log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date lastDataTime() {
|
||||
return pump.lastConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBaseBasalRate() {
|
||||
return pump.currentBasal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
|
||||
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
|
||||
|
@ -513,49 +332,6 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
|
||||
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
|
||||
insulin = configBuilderPlugin.applyBolusConstraints(insulin);
|
||||
// needs to be rounded
|
||||
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
|
||||
insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep);
|
||||
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) {
|
||||
result.enacted = false;
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.duration = pump.extendedBolusRemainingMinutes;
|
||||
result.absolute = pump.extendedBolusAbsoluteRate;
|
||||
result.isPercent = false;
|
||||
result.isTempCancel = false;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin);
|
||||
return result;
|
||||
}
|
||||
boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours);
|
||||
if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) {
|
||||
result.enacted = true;
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
result.isTempCancel = false;
|
||||
result.duration = pump.extendedBolusRemainingMinutes;
|
||||
result.absolute = pump.extendedBolusAbsoluteRate;
|
||||
result.bolusDelivered = pump.extendedBolusAmount;
|
||||
result.isPercent = false;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setExtendedBolus: OK");
|
||||
return result;
|
||||
}
|
||||
result.enacted = false;
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
|
||||
log.error("setExtendedBolus: Failed to extended bolus");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult cancelTempBasal(boolean force) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
|
@ -581,257 +357,8 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult cancelExtendedBolus() {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (runningEB != null) {
|
||||
sExecutionService.extendedBolusStop();
|
||||
result.enacted = true;
|
||||
result.isTempCancel = true;
|
||||
}
|
||||
if (!pump.isExtendedInProgress) {
|
||||
result.success = true;
|
||||
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
|
||||
if (Config.logPumpActions)
|
||||
log.debug("cancelExtendedBolus: OK");
|
||||
return result;
|
||||
} else {
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
|
||||
log.error("cancelExtendedBolus: Failed to cancel extended bolus");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(String from) {
|
||||
if (sExecutionService != null) {
|
||||
sExecutionService.connect(from);
|
||||
pumpDescription.basalStep = pump.basalStep;
|
||||
pumpDescription.bolusStep = pump.bolusStep;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return sExecutionService != null && sExecutionService.isConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnecting() {
|
||||
return sExecutionService != null && sExecutionService.isConnecting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String from) {
|
||||
if (sExecutionService != null) sExecutionService.disconnect(from);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopConnecting() {
|
||||
if (sExecutionService != null) sExecutionService.stopConnecting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPumpStatus() {
|
||||
if (sExecutionService != null) sExecutionService.getPumpStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getJSONStatus() {
|
||||
if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) {
|
||||
return null;
|
||||
}
|
||||
JSONObject pumpjson = new JSONObject();
|
||||
JSONObject battery = new JSONObject();
|
||||
JSONObject status = new JSONObject();
|
||||
JSONObject extended = new JSONObject();
|
||||
try {
|
||||
battery.put("percent", pump.batteryRemaining);
|
||||
status.put("status", pump.pumpSuspended ? "suspended" : "normal");
|
||||
status.put("timestamp", DateUtil.toISOString(pump.lastConnection));
|
||||
extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION);
|
||||
extended.put("PumpIOB", pump.iob);
|
||||
if (pump.lastBolusTime.getTime() != 0) {
|
||||
extended.put("LastBolus", pump.lastBolusTime.toLocaleString());
|
||||
extended.put("LastBolusAmount", pump.lastBolusAmount);
|
||||
}
|
||||
TemporaryBasal tb = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (tb != null) {
|
||||
extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis()));
|
||||
extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date));
|
||||
extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes());
|
||||
}
|
||||
ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (eb != null) {
|
||||
extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate());
|
||||
extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date));
|
||||
extended.put("ExtendedBolusRemaining", eb.getPlannedRemainingMinutes());
|
||||
}
|
||||
extended.put("BaseBasalRate", getBaseBasalRate());
|
||||
try {
|
||||
extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
pumpjson.put("battery", battery);
|
||||
pumpjson.put("status", status);
|
||||
pumpjson.put("extended", extended);
|
||||
pumpjson.put("reservoir", (int) pump.reservoirRemainingUnits);
|
||||
pumpjson.put("clock", DateUtil.toISOString(new Date()));
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return pumpjson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceID() {
|
||||
return pump.serialNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpDescription getPumpDescription() {
|
||||
return pumpDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* DanaR interface
|
||||
*/
|
||||
|
||||
@Override
|
||||
public PumpEnactResult loadHistory(byte type) {
|
||||
return sExecutionService.loadHistory(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult loadEvents() {
|
||||
return sExecutionService.loadEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constraint interface
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isLoopEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosedModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutosensModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAMAModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSMBModeEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Double applyBasalConstraints(Double absoluteRate) {
|
||||
double origAbsoluteRate = absoluteRate;
|
||||
if (pump != null) {
|
||||
if (absoluteRate > pump.maxBasal) {
|
||||
absoluteRate = pump.maxBasal;
|
||||
if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit)
|
||||
log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h");
|
||||
}
|
||||
}
|
||||
return absoluteRate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Integer applyBasalConstraints(Integer percentRate) {
|
||||
Integer origPercentRate = percentRate;
|
||||
if (percentRate < 0) percentRate = 0;
|
||||
if (percentRate > getPumpDescription().maxTempPercent)
|
||||
percentRate = getPumpDescription().maxTempPercent;
|
||||
if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
||||
log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%");
|
||||
return percentRate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Double applyBolusConstraints(Double insulin) {
|
||||
double origInsulin = insulin;
|
||||
if (pump != null) {
|
||||
if (insulin > pump.maxBolus) {
|
||||
insulin = pump.maxBolus;
|
||||
if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit)
|
||||
log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U");
|
||||
}
|
||||
}
|
||||
return insulin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer applyCarbsConstraints(Integer carbs) {
|
||||
return carbs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double applyMaxIOBConstraints(Double maxIob) {
|
||||
return maxIob;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ProfileStore getProfile() {
|
||||
if (pump.lastSettingsRead.getTime() == 0)
|
||||
return null; // no info now
|
||||
return pump.createConvertedProfile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnits() {
|
||||
return pump.getUnits();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProfileName() {
|
||||
return pump.createConvertedProfileName();
|
||||
}
|
||||
|
||||
// Reply for sms communicator
|
||||
public String shortStatus(boolean veryShort) {
|
||||
String ret = "";
|
||||
if (pump.lastConnection.getTime() != 0) {
|
||||
Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime();
|
||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
||||
ret += "LastConn: " + agoMin + " minago\n";
|
||||
}
|
||||
if (pump.lastBolusTime.getTime() != 0) {
|
||||
ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n";
|
||||
}
|
||||
if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) {
|
||||
ret += "Temp: " + MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n";
|
||||
}
|
||||
if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n";
|
||||
}
|
||||
if (!veryShort) {
|
||||
ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n";
|
||||
}
|
||||
ret += "IOB: " + pump.iob + "U\n";
|
||||
ret += "Reserv: " + DecimalFormatter.to0Decimal(pump.reservoirRemainingUnits) + "U\n";
|
||||
ret += "Batt: " + pump.batteryRemaining + "\n";
|
||||
return ret;
|
||||
}
|
||||
// TODO: daily total constraint
|
||||
|
||||
}
|
||||
|
|
|
@ -13,13 +13,14 @@ import java.io.OutputStream;
|
|||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractSerialIOThread;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MessageHashTable_v2;
|
||||
import info.nightscout.utils.CRC;
|
||||
|
||||
/**
|
||||
* Created by mike on 17.07.2016.
|
||||
*/
|
||||
public class SerialIOThread extends Thread {
|
||||
public class SerialIOThread extends AbstractSerialIOThread {
|
||||
private static Logger log = LoggerFactory.getLogger(SerialIOThread.class);
|
||||
|
||||
private InputStream mInputStream = null;
|
||||
|
@ -29,10 +30,10 @@ public class SerialIOThread extends Thread {
|
|||
private boolean mKeepRunning = true;
|
||||
private byte[] mReadBuff = new byte[0];
|
||||
|
||||
MessageBase processedMessage;
|
||||
private MessageBase processedMessage;
|
||||
|
||||
public SerialIOThread(BluetoothSocket rfcommSocket) {
|
||||
super(SerialIOThread.class.toString());
|
||||
super();
|
||||
|
||||
mRfCommSocket = rfcommSocket;
|
||||
try {
|
||||
|
@ -138,6 +139,7 @@ public class SerialIOThread extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void sendMessage(MessageBase message) {
|
||||
if (!mRfCommSocket.isConnected()) {
|
||||
log.error("Socket not connected on sendMessage");
|
||||
|
@ -173,6 +175,7 @@ public class SerialIOThread extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String reason) {
|
||||
mKeepRunning = false;
|
||||
try {
|
||||
|
|
|
@ -40,6 +40,7 @@ public class MsgCheckValue_v2 extends MessageBase {
|
|||
pump.protocol = intFromBuff(bytes, 1, 1);
|
||||
pump.productCode = intFromBuff(bytes, 2, 1);
|
||||
if (pump.model != DanaRPump.EXPORT_MODEL) {
|
||||
pump.lastConnection = 0;
|
||||
Notification notification = new Notification(Notification.WRONG_DRIVER, MainApp.sResources.getString(R.string.pumpdrivercorrected), Notification.NORMAL);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
MainApp.getSpecificPlugin(DanaRPlugin.class).disconnect("Wrong Model");
|
||||
|
@ -48,7 +49,7 @@ public class MsgCheckValue_v2 extends MessageBase {
|
|||
MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginBase.PUMP, true);
|
||||
MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentEnabled(PluginBase.PUMP, false);
|
||||
MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentVisible(PluginBase.PUMP, false);
|
||||
DanaRPump.getInstance().lastConnection = new Date(0); // mark not initialized
|
||||
DanaRPump.getInstance().lastConnection = 0; // mark not initialized
|
||||
|
||||
//If profile coming from pump, switch it as well
|
||||
if(MainApp.getSpecificPlugin(DanaRPlugin.class).isEnabled(PluginBase.PROFILE)){
|
||||
|
@ -63,6 +64,7 @@ public class MsgCheckValue_v2 extends MessageBase {
|
|||
}
|
||||
|
||||
if (pump.protocol != 2) {
|
||||
pump.lastConnection = 0;
|
||||
Notification notification = new Notification(Notification.WRONG_DRIVER, MainApp.sResources.getString(R.string.pumpdrivercorrected), Notification.NORMAL);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
DanaRKoreanPlugin.getPlugin().disconnect("Wrong Model");
|
||||
|
|
|
@ -1,52 +1,66 @@
|
|||
package info.nightscout.androidaps.plugins.PumpDanaRv2.services;
|
||||
|
||||
import android.app.Service;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothSocket;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventInitializationChanged;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.events.EventPumpStatusChanged;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.*;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusProgress;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStart;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStartWithSpeed;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStop;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetActivateBasalProfile;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetBasalProfile;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetCarbsEntry;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetExtendedBolusStart;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetExtendedBolusStop;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStart;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStop;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTime;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingActiveProfile;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingBasal;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingGlucose;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMaxValues;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMeal;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatios;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatiosAll;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingPumpTime;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingShippingInfo;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatus;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBasic;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractDanaRExecutionService;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.SerialIOThread;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgCheckValue_v2;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgHistoryEvents_v2;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgSetAPSTempBasalStart_v2;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgSetHistoryEntry_v2;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgCheckValue_v2;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgStatusBolusExtended_v2;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgStatusTempBasal_v2;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
|
@ -54,47 +68,16 @@ import info.nightscout.utils.NSUpload;
|
|||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
public class DanaRv2ExecutionService extends Service {
|
||||
private static Logger log = LoggerFactory.getLogger(DanaRv2ExecutionService.class);
|
||||
|
||||
private String devName;
|
||||
|
||||
private SerialIOThread mSerialIOThread;
|
||||
private BluetoothSocket mRfcommSocket;
|
||||
private BluetoothDevice mBTDevice;
|
||||
|
||||
private IBinder mBinder = new LocalBinder();
|
||||
|
||||
private DanaRPump danaRPump;
|
||||
private Treatment bolusingTreatment = null;
|
||||
|
||||
private static Boolean connectionInProgress = false;
|
||||
|
||||
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
|
||||
public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
|
||||
|
||||
private long lastHistoryFetched = 0;
|
||||
|
||||
private BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
String action = intent.getAction();
|
||||
if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
|
||||
log.debug("Device was disconnected " + device.getName());//Device was disconnected
|
||||
if (mBTDevice != null && mBTDevice.getName() != null && mBTDevice.getName().equals(device.getName())) {
|
||||
if (mSerialIOThread != null) {
|
||||
mSerialIOThread.disconnect("BT disconnection broadcast");
|
||||
}
|
||||
MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public DanaRv2ExecutionService() {
|
||||
log = LoggerFactory.getLogger(DanaRv2ExecutionService.class);
|
||||
mBinder = new LocalBinder();
|
||||
|
||||
registerBus();
|
||||
MainApp.instance().getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED));
|
||||
danaRPump = DanaRPump.getInstance();
|
||||
}
|
||||
|
||||
public class LocalBinder extends Binder {
|
||||
|
@ -103,17 +86,6 @@ public class DanaRv2ExecutionService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
private void registerBus() {
|
||||
try {
|
||||
MainApp.bus().unregister(this);
|
||||
|
@ -138,35 +110,28 @@ public class DanaRv2ExecutionService extends Service {
|
|||
log.debug("EventAppExit finished");
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return mRfcommSocket != null && mRfcommSocket.isConnected();
|
||||
}
|
||||
|
||||
public boolean isConnecting() {
|
||||
return connectionInProgress;
|
||||
}
|
||||
|
||||
public void disconnect(String from) {
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventPreferenceChange pch) {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect(from);
|
||||
mSerialIOThread.disconnect("EventPreferenceChange");
|
||||
}
|
||||
|
||||
public void connect(String from) {
|
||||
if (danaRPump.password != -1 && danaRPump.password != SP.getInt(R.string.key_danar_password, -1)) {
|
||||
public void connect() {
|
||||
if (mDanaRPump.password != -1 && mDanaRPump.password != SP.getInt(R.string.key_danar_password, -1)) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.wrongpumppassword), R.raw.error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (connectionInProgress)
|
||||
if (mConnectionInProgress)
|
||||
return;
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
connectionInProgress = true;
|
||||
mConnectionInProgress = true;
|
||||
getBTSocketForSelectedPump();
|
||||
if (mRfcommSocket == null || mBTDevice == null) {
|
||||
connectionInProgress = false;
|
||||
mConnectionInProgress = false;
|
||||
return; // Device not found
|
||||
}
|
||||
|
||||
|
@ -187,48 +152,11 @@ public class DanaRv2ExecutionService extends Service {
|
|||
MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTED, 0));
|
||||
}
|
||||
|
||||
connectionInProgress = false;
|
||||
mConnectionInProgress = false;
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void stopConnecting() {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect("stopConnecting");
|
||||
}
|
||||
|
||||
private void getBTSocketForSelectedPump() {
|
||||
devName = SP.getString(MainApp.sResources.getString(R.string.key_danar_bt_name), "");
|
||||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
|
||||
if (bluetoothAdapter != null) {
|
||||
Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
|
||||
|
||||
for (BluetoothDevice device : bondedDevices) {
|
||||
if (devName.equals(device.getName())) {
|
||||
mBTDevice = device;
|
||||
try {
|
||||
mRfcommSocket = mBTDevice.createRfcommSocketToServiceRecord(SPP_UUID);
|
||||
} catch (IOException e) {
|
||||
log.error("Error creating socket: ", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.nobtadapter));
|
||||
}
|
||||
if (mBTDevice == null) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.devicenotfound));
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventPreferenceChange pch) {
|
||||
if (mSerialIOThread != null)
|
||||
mSerialIOThread.disconnect("EventPreferenceChange");
|
||||
}
|
||||
|
||||
public void getPumpStatus() {
|
||||
try {
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpstatus)));
|
||||
|
@ -238,7 +166,7 @@ public class DanaRv2ExecutionService extends Service {
|
|||
MsgStatusBolusExtended_v2 exStatusMsg = new MsgStatusBolusExtended_v2();
|
||||
MsgCheckValue_v2 checkValue = new MsgCheckValue_v2();
|
||||
|
||||
if (danaRPump.isNewPump) {
|
||||
if (mDanaRPump.isNewPump) {
|
||||
mSerialIOThread.sendMessage(checkValue);
|
||||
if (!checkValue.received) {
|
||||
return;
|
||||
|
@ -253,8 +181,8 @@ public class DanaRv2ExecutionService extends Service {
|
|||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingextendedbolusstatus)));
|
||||
mSerialIOThread.sendMessage(exStatusMsg);
|
||||
|
||||
Date now = new Date();
|
||||
if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !MainApp.getSpecificPlugin(DanaRv2Plugin.class).isInitialized()) {
|
||||
long now = System.currentTimeMillis();
|
||||
if (mDanaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRv2Plugin.class).isInitialized()) {
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpsettings)));
|
||||
mSerialIOThread.sendMessage(new MsgSettingShippingInfo());
|
||||
mSerialIOThread.sendMessage(new MsgSettingActiveProfile());
|
||||
|
@ -268,28 +196,28 @@ public class DanaRv2ExecutionService extends Service {
|
|||
mSerialIOThread.sendMessage(new MsgSettingProfileRatiosAll());
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumptime)));
|
||||
mSerialIOThread.sendMessage(new MsgSettingPumpTime());
|
||||
long timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
long timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
log.debug("Pump time difference: " + timeDiff + " seconds");
|
||||
if (Math.abs(timeDiff) > 10) {
|
||||
mSerialIOThread.sendMessage(new MsgSetTime(new Date()));
|
||||
mSerialIOThread.sendMessage(new MsgSettingPumpTime());
|
||||
timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
|
||||
log.debug("Pump time difference: " + timeDiff + " seconds");
|
||||
}
|
||||
danaRPump.lastSettingsRead = now;
|
||||
mDanaRPump.lastSettingsRead = now;
|
||||
}
|
||||
|
||||
loadEvents();
|
||||
|
||||
danaRPump.lastConnection = now;
|
||||
mDanaRPump.lastConnection = now;
|
||||
MainApp.bus().post(new EventDanaRNewStatus());
|
||||
MainApp.bus().post(new EventInitializationChanged());
|
||||
NSUpload.uploadDeviceStatus();
|
||||
if (danaRPump.dailyTotalUnits > danaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) {
|
||||
log.debug("Approaching daily limit: " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits);
|
||||
if (mDanaRPump.dailyTotalUnits > mDanaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) {
|
||||
log.debug("Approaching daily limit: " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits);
|
||||
Notification reportFail = new Notification(Notification.APPROACHING_DAILY_LIMIT, MainApp.sResources.getString(R.string.approachingdailylimit), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(reportFail));
|
||||
NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits + "U");
|
||||
NSUpload.uploadError(MainApp.sResources.getString(R.string.approachingdailylimit) + ": " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits + "U");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
|
@ -299,10 +227,10 @@ public class DanaRv2ExecutionService extends Service {
|
|||
|
||||
public boolean tempBasal(int percent, int durationInHours) {
|
||||
if (!isConnected()) return false;
|
||||
if (danaRPump.isTempBasalInProgress) {
|
||||
if (mDanaRPump.isTempBasalInProgress) {
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal)));
|
||||
mSerialIOThread.sendMessage(new MsgSetTempBasalStop());
|
||||
waitMsec(500);
|
||||
SystemClock.sleep(500);
|
||||
}
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.settingtempbasal)));
|
||||
mSerialIOThread.sendMessage(new MsgSetTempBasalStart(percent, durationInHours));
|
||||
|
@ -314,10 +242,10 @@ public class DanaRv2ExecutionService extends Service {
|
|||
|
||||
public boolean highTempBasal(int percent) {
|
||||
if (!isConnected()) return false;
|
||||
if (danaRPump.isTempBasalInProgress) {
|
||||
if (mDanaRPump.isTempBasalInProgress) {
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal)));
|
||||
mSerialIOThread.sendMessage(new MsgSetTempBasalStop());
|
||||
waitMsec(500);
|
||||
SystemClock.sleep(500);
|
||||
}
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.settingtempbasal)));
|
||||
mSerialIOThread.sendMessage(new MsgSetAPSTempBasalStart_v2(percent));
|
||||
|
@ -362,7 +290,7 @@ public class DanaRv2ExecutionService extends Service {
|
|||
if (BolusProgressDialog.stopPressed) return false;
|
||||
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.startingbolus)));
|
||||
bolusingTreatment = t;
|
||||
mBolusingTreatment = t;
|
||||
final int preferencesSpeed = SP.getInt(R.string.key_danars_bolusspeed, 0);
|
||||
MessageBase start;
|
||||
if (preferencesSpeed == 0)
|
||||
|
@ -390,7 +318,7 @@ public class DanaRv2ExecutionService extends Service {
|
|||
return false;
|
||||
}
|
||||
while (!stop.stopped && !start.failed) {
|
||||
waitMsec(100);
|
||||
SystemClock.sleep(100);
|
||||
if ((System.currentTimeMillis() - progress.lastReceive) > 15 * 1000L) { // if i didn't receive status for more than 15 sec expecting broken comm
|
||||
stop.stopped = true;
|
||||
stop.forced = true;
|
||||
|
@ -403,7 +331,7 @@ public class DanaRv2ExecutionService extends Service {
|
|||
bolusingEvent.t = t;
|
||||
bolusingEvent.percent = 99;
|
||||
|
||||
bolusingTreatment = null;
|
||||
mBolusingTreatment = null;
|
||||
int speed = 12;
|
||||
switch (preferencesSpeed) {
|
||||
case 0:
|
||||
|
@ -440,14 +368,14 @@ public class DanaRv2ExecutionService extends Service {
|
|||
|
||||
public void bolusStop() {
|
||||
if (Config.logDanaBTComm)
|
||||
log.debug("bolusStop >>>>> @ " + (bolusingTreatment == null ? "" : bolusingTreatment.insulin));
|
||||
log.debug("bolusStop >>>>> @ " + (mBolusingTreatment == null ? "" : mBolusingTreatment.insulin));
|
||||
MsgBolusStop stop = new MsgBolusStop();
|
||||
stop.forced = true;
|
||||
if (isConnected()) {
|
||||
mSerialIOThread.sendMessage(stop);
|
||||
while (!stop.stopped) {
|
||||
mSerialIOThread.sendMessage(stop);
|
||||
waitMsec(200);
|
||||
SystemClock.sleep(200);
|
||||
}
|
||||
} else {
|
||||
stop.stopped = true;
|
||||
|
@ -464,57 +392,10 @@ public class DanaRv2ExecutionService extends Service {
|
|||
return true;
|
||||
}
|
||||
|
||||
public PumpEnactResult loadHistory(byte type) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
if (!isConnected()) return result;
|
||||
MessageBase msg = null;
|
||||
switch (type) {
|
||||
case RecordTypes.RECORD_TYPE_ALARM:
|
||||
msg = new MsgHistoryAlarm();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_BASALHOUR:
|
||||
msg = new MsgHistoryBasalHour();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_BOLUS:
|
||||
msg = new MsgHistoryBolus();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_CARBO:
|
||||
msg = new MsgHistoryCarbo();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_DAILY:
|
||||
msg = new MsgHistoryDailyInsulin();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_ERROR:
|
||||
msg = new MsgHistoryError();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_GLUCOSE:
|
||||
msg = new MsgHistoryGlucose();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_REFILL:
|
||||
msg = new MsgHistoryRefill();
|
||||
break;
|
||||
case RecordTypes.RECORD_TYPE_SUSPEND:
|
||||
msg = new MsgHistorySuspend();
|
||||
break;
|
||||
}
|
||||
MsgHistoryDone done = new MsgHistoryDone();
|
||||
mSerialIOThread.sendMessage(new MsgPCCommStart());
|
||||
waitMsec(400);
|
||||
mSerialIOThread.sendMessage(msg);
|
||||
while (!done.received && mRfcommSocket.isConnected()) {
|
||||
waitMsec(100);
|
||||
}
|
||||
waitMsec(200);
|
||||
mSerialIOThread.sendMessage(new MsgPCCommStop());
|
||||
result.success = true;
|
||||
result.comment = "OK";
|
||||
return result;
|
||||
}
|
||||
|
||||
public PumpEnactResult loadEvents() {
|
||||
if (!isConnected())
|
||||
return new PumpEnactResult().success(false);
|
||||
waitMsec(300);
|
||||
SystemClock.sleep(300);
|
||||
MsgHistoryEvents_v2 msg;
|
||||
if (lastHistoryFetched == 0) {
|
||||
msg = new MsgHistoryEvents_v2();
|
||||
|
@ -525,9 +406,9 @@ public class DanaRv2ExecutionService extends Service {
|
|||
}
|
||||
mSerialIOThread.sendMessage(msg);
|
||||
while (!msg.done && mRfcommSocket.isConnected()) {
|
||||
waitMsec(100);
|
||||
SystemClock.sleep(100);
|
||||
}
|
||||
waitMsec(200);
|
||||
SystemClock.sleep(200);
|
||||
if (MsgHistoryEvents_v2.lastEventTimeLoaded != 0)
|
||||
lastHistoryFetched = MsgHistoryEvents_v2.lastEventTimeLoaded - 45 * 60 * 1000L; //always load last 45 min;
|
||||
else
|
||||
|
@ -543,13 +424,10 @@ public class DanaRv2ExecutionService extends Service {
|
|||
mSerialIOThread.sendMessage(msgSet);
|
||||
MsgSetActivateBasalProfile msgActivate = new MsgSetActivateBasalProfile((byte) 0);
|
||||
mSerialIOThread.sendMessage(msgActivate);
|
||||
danaRPump.lastSettingsRead = new Date(0); // force read full settings
|
||||
mDanaRPump.lastSettingsRead = 0; // force read full settings
|
||||
getPumpStatus();
|
||||
MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING));
|
||||
return true;
|
||||
}
|
||||
|
||||
private void waitMsec(long msecs) {
|
||||
SystemClock.sleep(msecs);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue