From 4cef8db54b67cbe4ec0cf967d5c6e4a6a07358fc Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 29 Jan 2018 11:24:03 +0100 Subject: [PATCH] Dana plugin refactoring --- .../PumpDanaR/AbstractDanaRPlugin.java | 557 ++++++++++++++++++ .../plugins/PumpDanaR/DanaRFragment.java | 7 +- .../plugins/PumpDanaR/DanaRPlugin.java | 543 +---------------- .../plugins/PumpDanaR/DanaRPump.java | 4 +- .../plugins/PumpDanaR/SerialIOThread.java | 9 +- .../PumpDanaR/comm/MsgInitConnStatusTime.java | 2 +- .../PumpDanaR/comm/MsgSettingBasal.java | 2 +- .../PumpDanaR/comm/MsgSettingMeal.java | 9 +- .../AbstractDanaRExecutionService.java | 225 +++++++ .../services/AbstractSerialIOThread.java | 13 + .../services/DanaRExecutionService.java | 286 ++------- .../PumpDanaRKorean/DanaRKoreanPlugin.java | 546 +---------------- .../PumpDanaRKorean/SerialIOThread.java | 9 +- .../comm/MsgInitConnStatusTime_k.java | 2 +- .../comm/MsgSettingBasal_k.java | 2 +- .../services/DanaRKoreanExecutionService.java | 255 ++------ .../plugins/PumpDanaRS/DanaRSPlugin.java | 12 +- .../PumpDanaRS/services/DanaRSService.java | 6 +- .../plugins/PumpDanaRv2/DanaRv2Plugin.java | 485 +-------------- .../plugins/PumpDanaRv2/SerialIOThread.java | 9 +- .../PumpDanaRv2/comm/MsgCheckValue_v2.java | 4 +- .../services/DanaRv2ExecutionService.java | 250 ++------ 22 files changed, 1030 insertions(+), 2207 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractSerialIOThread.java diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java new file mode 100644 index 0000000000..ea47303fb6 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java @@ -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 + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java index eaf8a494e5..1ca54a7eb6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java @@ -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); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java index 3a11ebe0a6..9a0be55897 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java @@ -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 - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java index 9f88011c96..0e1a9ceb75 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java @@ -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 = ""; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java index a333faecea..2f377a566a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java @@ -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 { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java index 17f90a1ba7..fe0d280113 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java @@ -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); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java index e1a7e45315..a47803c1b0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java @@ -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; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java index 2d54d4f4a2..5d7b4b65ac 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java @@ -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)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java new file mode 100644 index 0000000000..d853c9abf1 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java @@ -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 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; + } + + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractSerialIOThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractSerialIOThread.java new file mode 100644 index 0000000000..1cca0b2512 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractSerialIOThread.java @@ -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); +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java index 0aa4b176c7..63215464a8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java @@ -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 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"); } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java index e92febada6..58392e65f9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java @@ -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 - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java index 8672afdcb0..9a8f3edb05 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java @@ -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 { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java index 641dce79f3..3cf47b656f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java @@ -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)) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java index 72a8be4e42..5c8b40b959 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java @@ -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; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java index 4efff4a5ad..6d1ccc132d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java @@ -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 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); - } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java index cfdbdeb5cd..9978880e08 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java @@ -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"; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java index 7790257640..1a1f74b645 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java @@ -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; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java index 3e1aca22e0..34a5b2381b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java @@ -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 - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java index 343a176e56..a12e2085aa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java @@ -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 { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java index 9869ef0895..60133d8d25 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java @@ -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"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java index 71a2f9ac79..81b5837511 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java @@ -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 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); - } }