DanaRKoreanPlugin -> kt

This commit is contained in:
Milos Kozak 2021-04-10 15:32:47 +02:00
parent d898a374e6
commit 2b58bc8306
2 changed files with 304 additions and 375 deletions

View file

@ -1,375 +0,0 @@
package info.nightscout.androidaps.danaRKorean;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import androidx.annotation.NonNull;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.dana.DanaPump;
import info.nightscout.androidaps.danaRKorean.services.DanaRKoreanExecutionService;
import info.nightscout.androidaps.danar.AbstractDanaRPlugin;
import info.nightscout.androidaps.danar.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.CommandQueueProvider;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpSync;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.Round;
import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.rx.AapsSchedulers;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
import io.reactivex.disposables.CompositeDisposable;
@Singleton
public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
private final CompositeDisposable disposable = new CompositeDisposable();
private final AAPSLogger aapsLogger;
private final Context context;
private final ResourceHelper resourceHelper;
private final ConstraintChecker constraintChecker;
private final FabricPrivacy fabricPrivacy;
@Inject
public DanaRKoreanPlugin(
HasAndroidInjector injector,
AAPSLogger aapsLogger,
AapsSchedulers aapsSchedulers,
RxBusWrapper rxBus,
Context context,
ResourceHelper resourceHelper,
ConstraintChecker constraintChecker,
ActivePluginProvider activePlugin,
SP sp,
CommandQueueProvider commandQueue,
DanaPump danaPump,
DateUtil dateUtil,
FabricPrivacy fabricPrivacy,
PumpSync pumpSync
) {
super(injector, danaPump, resourceHelper, constraintChecker, aapsLogger, aapsSchedulers, commandQueue, rxBus, activePlugin, sp, dateUtil, pumpSync);
this.aapsLogger = aapsLogger;
this.context = context;
this.resourceHelper = resourceHelper;
this.constraintChecker = constraintChecker;
this.fabricPrivacy = fabricPrivacy;
getPluginDescription().description(R.string.description_pump_dana_r_korean);
useExtendedBoluses = sp.getBoolean(R.string.key_danar_useextended, false);
pumpDescription.setPumpDescription(PumpType.DANA_R_KOREAN);
}
@Override
protected void onStart() {
Intent intent = new Intent(context, DanaRKoreanExecutionService.class);
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
disposable.add(rxBus
.toObservable(EventPreferenceChange.class)
.observeOn(aapsSchedulers.getIo())
.subscribe(event -> {
if (isEnabled(PluginType.PUMP)) {
boolean previousValue = useExtendedBoluses;
useExtendedBoluses = sp.getBoolean(R.string.key_danar_useextended, false);
if (useExtendedBoluses != previousValue && pumpSync.expectedPumpState().getExtendedBolus() != null) {
sExecutionService.extendedBolusStop();
}
}
}, fabricPrivacy::logException)
);
disposable.add(rxBus
.toObservable(EventAppExit.class)
.observeOn(aapsSchedulers.getIo())
.subscribe(event -> context.unbindService(mConnection), fabricPrivacy::logException)
);
super.onStart();
}
@Override
protected void onStop() {
context.unbindService(mConnection);
disposable.clear();
super.onStop();
}
private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
aapsLogger.debug(LTag.PUMP, "Service is disconnected");
sExecutionService = null;
}
public void onServiceConnected(ComponentName name, IBinder service) {
aapsLogger.debug(LTag.PUMP, "Service is connected");
DanaRKoreanExecutionService.LocalBinder mLocalBinder = (DanaRKoreanExecutionService.LocalBinder) service;
sExecutionService = mLocalBinder.getServiceInstance();
}
};
// Plugin base interface
@NonNull
@Override
public String getName() {
return resourceHelper.gs(R.string.danarkoreanpump);
}
@Override
public int getPreferencesId() {
return R.xml.pref_danarkorean;
}
// Pump interface
@Override
public boolean isFakingTempsByExtendedBoluses() {
return useExtendedBoluses;
}
@Override
public boolean isInitialized() {
return danaPump.getLastConnection() > 0 && danaPump.getMaxBasal() > 0 && !danaPump.isConfigUD() && !danaPump.isEasyModeEnabled() && danaPump.isExtendedBolusEnabled() && danaPump.isPasswordOK();
}
@Override
public boolean isHandshakeInProgress() {
return sExecutionService != null && sExecutionService.isHandshakeInProgress();
}
@Override
public void finishHandshaking() {
sExecutionService.finishHandshaking();
}
@NonNull @Override
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
EventOverviewBolusProgress.Treatment t = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB);
boolean connectionOK = false;
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0)
connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t);
PumpEnactResult result = new PumpEnactResult(getInjector());
result.success(connectionOK && Math.abs(detailedBolusInfo.insulin - t.insulin) < pumpDescription.getBolusStep())
.bolusDelivered(t.insulin)
.carbsDelivered(detailedBolusInfo.carbs);
if (!result.getSuccess())
result.comment(resourceHelper.gs(R.string.boluserrorcode, detailedBolusInfo.insulin, t.insulin, danaPump.getBolusStartErrorCode()));
else
result.comment(R.string.ok);
aapsLogger.debug(LTag.PUMP, "deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.getBolusDelivered());
detailedBolusInfo.insulin = t.insulin;
detailedBolusInfo.timestamp = System.currentTimeMillis();
if (detailedBolusInfo.insulin > 0)
pumpSync.syncBolusWithPumpId(
detailedBolusInfo.timestamp,
detailedBolusInfo.insulin,
detailedBolusInfo.getBolusType(),
dateUtil._now(),
PumpType.DANA_R_KOREAN,
serialNumber()
);
if (detailedBolusInfo.carbs > 0)
pumpSync.syncCarbsWithTimestamp(
detailedBolusInfo.timestamp + T.mins(detailedBolusInfo.carbTime).msecs(),
detailedBolusInfo.carbs,
null,
PumpType.DANA_R_KOREAN,
serialNumber()
);
return result;
} else {
PumpEnactResult result = new PumpEnactResult(getInjector());
result.success(false).bolusDelivered(0d).carbsDelivered(0d).comment(R.string.invalidinput);
aapsLogger.error("deliverTreatment: Invalid input");
return result;
}
}
// This is called from APS
@NonNull @Override
public PumpEnactResult setTempBasalAbsolute(double absoluteRate, int durationInMinutes, @NonNull Profile profile, boolean enforceNew, @NonNull PumpSync.TemporaryBasalType tbrType) {
// Recheck pump status if older than 30 min
//This should not be needed while using queue because connection should be done before calling this
PumpEnactResult result = new PumpEnactResult(getInjector());
absoluteRate = constraintChecker.applyBasalConstraints(new Constraint<>(absoluteRate), profile).value();
final boolean doTempOff = getBaseBasalRate() - absoluteRate == 0d && absoluteRate >= 0.10d;
final boolean doLowTemp = absoluteRate < getBaseBasalRate() || absoluteRate < 0.10d;
final boolean doHighTemp = absoluteRate > getBaseBasalRate() && !useExtendedBoluses;
final boolean doExtendedTemp = absoluteRate > getBaseBasalRate() && useExtendedBoluses;
if (doTempOff) {
// If extended in progress
if (danaPump.isExtendedInProgress() && useExtendedBoluses) {
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Stopping extended bolus (doTempOff)");
return cancelExtendedBolus();
}
// If temp in progress
if (danaPump.isTempBasalInProgress()) {
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Stopping temp basal (doTempOff)");
return cancelRealTempBasal();
}
result.success(true).enacted(false).percent(100).isPercent(true).isTempCancel(true);
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: doTempOff OK");
return result;
}
if (doLowTemp || doHighTemp) {
int percentRate = Double.valueOf(absoluteRate / getBaseBasalRate() * 100).intValue();
// Any basal less than 0.10u/h will be dumped once per hour, not every 4 minutes. So if it's less than .10u/h, set a zero temp.
if (absoluteRate < 0.10d) percentRate = 0;
if (percentRate < 100) percentRate = Round.ceilTo((double) percentRate, 10d).intValue();
else percentRate = Round.floorTo((double) percentRate, 10d).intValue();
if (percentRate > getPumpDescription().getMaxTempPercent()) {
percentRate = getPumpDescription().getMaxTempPercent();
}
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Calculated percent rate: " + percentRate);
// If extended in progress
if (danaPump.isExtendedInProgress() && useExtendedBoluses) {
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Stopping extended bolus (doLowTemp || doHighTemp)");
result = cancelExtendedBolus();
if (!result.getSuccess()) {
aapsLogger.error("setTempBasalAbsolute: Failed to stop previous extended bolus (doLowTemp || doHighTemp)");
return result;
}
}
// Check if some temp is already in progress
if (danaPump.isTempBasalInProgress()) {
// Correct basal already set ?
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: currently running: " + danaPump.temporaryBasalToString());
if (danaPump.getTempBasalPercent() == percentRate && danaPump.getTempBasalRemainingMin() > 4) {
if (enforceNew) {
cancelTempBasal(true);
} else {
result.success(true).percent(percentRate).enacted(false).duration(danaPump.getTempBasalRemainingMin()).isPercent(true).isTempCancel(false);
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Correct temp basal already set (doLowTemp || doHighTemp)");
return result;
}
}
}
// Convert duration from minutes to hours
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Setting temp basal " + percentRate + "% for " + durationInMinutes + " minutes (doLowTemp || doHighTemp)");
return setTempBasalPercent(percentRate, durationInMinutes, profile, false, tbrType);
}
if (doExtendedTemp) {
// Check if some temp is already in progress
if (danaPump.isTempBasalInProgress()) {
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Stopping temp basal (doExtendedTemp)");
result = cancelRealTempBasal();
// Check for proper result
if (!result.getSuccess()) {
aapsLogger.error("setTempBasalAbsolute: Failed to stop previous temp basal (doExtendedTemp)");
return result;
}
}
// Calculate # of halfHours from minutes
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
// We keep current basal running so need to sub current basal
double extendedRateToSet = absoluteRate - getBaseBasalRate();
extendedRateToSet = constraintChecker.applyBasalConstraints(new Constraint<>(extendedRateToSet), profile).value();
// needs to be rounded to 0.1
extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.getExtendedBolusStep() * 2); // *2 because of half hours
// What is current rate of extended bolusing in u/h?
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Extended bolus in progress: " + (danaPump.isExtendedInProgress()) + " rate: " + danaPump.getExtendedBolusAbsoluteRate() + "U/h duration remaining: " + danaPump.getExtendedBolusRemainingMinutes() + "min");
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Rate to set: " + extendedRateToSet + "U/h");
// Compare with extended rate in progress
if (danaPump.isExtendedInProgress() && Math.abs(danaPump.getExtendedBolusAbsoluteRate() - extendedRateToSet) < getPumpDescription().getExtendedBolusStep()) {
// correct extended already set
result.success(true).absolute(danaPump.getExtendedBolusAbsoluteRate()).enacted(false).duration(danaPump.getExtendedBolusRemainingMinutes()).isPercent(false).isTempCancel(false);
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Correct extended already set");
return result;
}
// Now set new extended, no need to to stop previous (if running) because it's replaced
double extendedAmount = extendedRateToSet / 2 * durationInHalfHours;
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Setting extended: " + extendedAmount + "U half hours: " + durationInHalfHours);
result = setExtendedBolus(extendedAmount, durationInMinutes);
if (!result.getSuccess()) {
aapsLogger.error("setTempBasalAbsolute: Failed to set extended bolus");
return result;
}
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Extended bolus set ok");
result.absolute(result.getAbsolute() + getBaseBasalRate());
return result;
}
// We should never end here
aapsLogger.error("setTempBasalAbsolute: Internal error");
result.success(false).comment("Internal error");
return result;
}
@NonNull @Override
public PumpEnactResult cancelTempBasal(boolean force) {
if (danaPump.isTempBasalInProgress())
return cancelRealTempBasal();
if (danaPump.isExtendedInProgress() && useExtendedBoluses) {
return cancelExtendedBolus();
}
PumpEnactResult result = new PumpEnactResult(getInjector());
result.success(true).enacted(false).comment(R.string.ok).isTempCancel(true);
return result;
}
@NonNull @Override
public PumpType model() {
return PumpType.DANA_R_KOREAN;
}
private PumpEnactResult cancelRealTempBasal() {
PumpEnactResult result = new PumpEnactResult(getInjector());
if (danaPump.isTempBasalInProgress()) {
sExecutionService.tempBasalStop();
if (!danaPump.isTempBasalInProgress()) {
pumpSync.syncStopTemporaryBasalWithPumpId(
dateUtil._now(),
dateUtil._now(),
getPumpDescription().getPumpType(),
serialNumber()
);
result.success(true).enacted(true).isTempCancel(true);
} else
result.success(false).enacted(false).isTempCancel(true);
} else {
result.success(true).isTempCancel(true).comment(R.string.ok);
aapsLogger.debug(LTag.PUMP, "cancelRealTempBasal: OK");
}
return result;
}
@NonNull @Override
public PumpEnactResult loadEvents() {
return new PumpEnactResult(getInjector()); // no history, not needed
}
@NonNull @Override
public PumpEnactResult setUserOptions() {
return new PumpEnactResult(getInjector());
}
}

View file

@ -0,0 +1,304 @@
package info.nightscout.androidaps.danaRKorean
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.dana.DanaPump
import info.nightscout.androidaps.danaRKorean.services.DanaRKoreanExecutionService
import info.nightscout.androidaps.danar.AbstractDanaRPlugin
import info.nightscout.androidaps.danar.R
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.interfaces.PumpSync.TemporaryBasalType
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.rxkotlin.plusAssign
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.abs
import kotlin.math.max
@Singleton
class DanaRKoreanPlugin @Inject constructor(
injector: HasAndroidInjector,
aapsLogger: AAPSLogger,
aapsSchedulers: AapsSchedulers,
rxBus: RxBusWrapper,
private val context: Context,
resourceHelper: ResourceHelper,
constraintChecker: ConstraintChecker,
activePlugin: ActivePluginProvider,
sp: SP,
commandQueue: CommandQueueProvider,
danaPump: DanaPump,
dateUtil: DateUtil,
private val fabricPrivacy: FabricPrivacy,
pumpSync: PumpSync
) : AbstractDanaRPlugin(injector, danaPump, resourceHelper, constraintChecker, aapsLogger, aapsSchedulers, commandQueue, rxBus, activePlugin, sp, dateUtil, pumpSync) {
init {
pluginDescription.description(R.string.description_pump_dana_r_korean)
useExtendedBoluses = sp.getBoolean(R.string.key_danar_useextended, false)
pumpDescription.setPumpDescription(PumpType.DANA_R_KOREAN)
}
override fun onStart() {
context.bindService(Intent(context, DanaRKoreanExecutionService::class.java), mConnection, Context.BIND_AUTO_CREATE)
disposable += rxBus
.toObservable(EventPreferenceChange::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({
if (isEnabled(PluginType.PUMP)) {
val previousValue = useExtendedBoluses
useExtendedBoluses = sp.getBoolean(R.string.key_danar_useextended, false)
if (useExtendedBoluses != previousValue && pumpSync.expectedPumpState().extendedBolus != null) {
sExecutionService.extendedBolusStop()
}
}
}, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventAppExit::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ context.unbindService(mConnection) }, fabricPrivacy::logException)
super.onStart()
}
override fun onStop() {
context.unbindService(mConnection)
disposable.clear()
super.onStop()
}
private val mConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName) {
aapsLogger.debug(LTag.PUMP, "Service is disconnected")
sExecutionService = null
}
override fun onServiceConnected(name: ComponentName, service: IBinder) {
aapsLogger.debug(LTag.PUMP, "Service is connected")
val mLocalBinder = service as DanaRKoreanExecutionService.LocalBinder
sExecutionService = mLocalBinder.serviceInstance
}
}
// Plugin base interface
override val name: String
get() = resourceHelper.gs(R.string.danarkoreanpump)
override val preferencesId: Int
get() = R.xml.pref_danarkorean
// Pump interface
override val isFakingTempsByExtendedBoluses: Boolean
get() = useExtendedBoluses
override fun isInitialized(): Boolean =
danaPump.lastConnection > 0 && danaPump.maxBasal > 0 && !danaPump.isConfigUD && !danaPump.isEasyModeEnabled && danaPump.isExtendedBolusEnabled && danaPump.isPasswordOK
override fun isHandshakeInProgress(): Boolean =
sExecutionService != null && sExecutionService.isHandshakeInProgress
override fun finishHandshaking() {
sExecutionService.finishHandshaking()
}
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(Constraint(detailedBolusInfo.insulin)).value()
if (detailedBolusInfo.carbs > 0) throw IllegalArgumentException()
return if (detailedBolusInfo.insulin > 0) {
val t = EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB)
var connectionOK = false
if (detailedBolusInfo.insulin > 0)
connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, detailedBolusInfo.carbs.toInt(), detailedBolusInfo.carbTime.toLong(), t)
val result = PumpEnactResult(injector)
result.success(connectionOK && abs(detailedBolusInfo.insulin - t.insulin) < pumpDescription.bolusStep)
.bolusDelivered(t.insulin)
if (!result.success) result.comment(resourceHelper.gs(R.string.boluserrorcode, detailedBolusInfo.insulin, t.insulin, danaPump.bolusStartErrorCode)) else result.comment(R.string.ok)
aapsLogger.debug(LTag.PUMP, "deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered)
detailedBolusInfo.insulin = t.insulin
detailedBolusInfo.timestamp = dateUtil._now()
if (detailedBolusInfo.insulin > 0) pumpSync.syncBolusWithPumpId(
detailedBolusInfo.timestamp,
detailedBolusInfo.insulin,
detailedBolusInfo.bolusType,
dateUtil._now(),
PumpType.DANA_R_KOREAN,
serialNumber()
)
result
} else {
val result = PumpEnactResult(injector)
result.success(false).bolusDelivered(0.0).carbsDelivered(0.0).comment(R.string.invalidinput)
aapsLogger.error("deliverTreatment: Invalid input")
result
}
}
// This is called from APS
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: TemporaryBasalType): PumpEnactResult {
// Recheck pump status if older than 30 min
//This should not be needed while using queue because connection should be done before calling this
var result = PumpEnactResult(injector)
val absoluteRateAfterConstraint = constraintChecker.applyBasalConstraints(Constraint(absoluteRate), profile).value()
val doTempOff = baseBasalRate - absoluteRateAfterConstraint == 0.0 && absoluteRateAfterConstraint >= 0.10
val doLowTemp = absoluteRateAfterConstraint < baseBasalRate || absoluteRateAfterConstraint < 0.10
val doHighTemp = absoluteRateAfterConstraint > baseBasalRate && !useExtendedBoluses
val doExtendedTemp = absoluteRateAfterConstraint > baseBasalRate && useExtendedBoluses
if (doTempOff) {
// If extended in progress
if (danaPump.isExtendedInProgress && useExtendedBoluses) {
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Stopping extended bolus (doTempOff)")
return cancelExtendedBolus()
}
// If temp in progress
if (danaPump.isTempBasalInProgress) {
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Stopping temp basal (doTempOff)")
return cancelRealTempBasal()
}
result.success(true).enacted(false).percent(100).isPercent(true).isTempCancel(true)
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: doTempOff OK")
return result
}
if (doLowTemp || doHighTemp) {
var percentRate: Int = java.lang.Double.valueOf(absoluteRateAfterConstraint / baseBasalRate * 100).toInt()
// Any basal less than 0.10u/h will be dumped once per hour, not every 4 minutes. So if it's less than .10u/h, set a zero temp.
if (absoluteRateAfterConstraint < 0.10) percentRate = 0
percentRate = if (percentRate < 100) Round.ceilTo(percentRate.toDouble(), 10.0).toInt() else Round.floorTo(percentRate.toDouble(), 10.0).toInt()
if (percentRate > pumpDescription.maxTempPercent) {
percentRate = pumpDescription.maxTempPercent
}
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Calculated percent rate: $percentRate")
// If extended in progress
if (danaPump.isExtendedInProgress && useExtendedBoluses) {
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Stopping extended bolus (doLowTemp || doHighTemp)")
result = cancelExtendedBolus()
if (!result.success) {
aapsLogger.error("setTempBasalAbsolute: Failed to stop previous extended bolus (doLowTemp || doHighTemp)")
return result
}
}
// Check if some temp is already in progress
if (danaPump.isTempBasalInProgress) {
// Correct basal already set ?
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: currently running: " + danaPump.temporaryBasalToString())
if (danaPump.tempBasalPercent == percentRate && danaPump.tempBasalRemainingMin > 4) {
if (enforceNew) {
cancelTempBasal(true)
} else {
result.success(true).percent(percentRate).enacted(false).duration(danaPump.tempBasalRemainingMin).isPercent(true).isTempCancel(false)
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Correct temp basal already set (doLowTemp || doHighTemp)")
return result
}
}
}
// Convert duration from minutes to hours
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Setting temp basal $percentRate% for $durationInMinutes minutes (doLowTemp || doHighTemp)")
return setTempBasalPercent(percentRate, durationInMinutes, profile, false, tbrType)
}
if (doExtendedTemp) {
// Check if some temp is already in progress
if (danaPump.isTempBasalInProgress) {
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Stopping temp basal (doExtendedTemp)")
result = cancelRealTempBasal()
// Check for proper result
if (!result.success) {
aapsLogger.error("setTempBasalAbsolute: Failed to stop previous temp basal (doExtendedTemp)")
return result
}
}
// Calculate # of halfHours from minutes
val durationInHalfHours = max(durationInMinutes / 30, 1)
// We keep current basal running so need to sub current basal
var extendedRateToSet: Double = absoluteRateAfterConstraint - baseBasalRate
extendedRateToSet = constraintChecker.applyBasalConstraints(Constraint(extendedRateToSet), profile).value()
// needs to be rounded to 0.1
extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.extendedBolusStep * 2) // *2 because of half hours
// What is current rate of extended bolusing in u/h?
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Extended bolus in progress: " + danaPump.isExtendedInProgress + " rate: " + danaPump.extendedBolusAbsoluteRate + "U/h duration remaining: " + danaPump.extendedBolusRemainingMinutes + "min")
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Rate to set: " + extendedRateToSet + "U/h")
// Compare with extended rate in progress
if (danaPump.isExtendedInProgress && abs(danaPump.extendedBolusAbsoluteRate - extendedRateToSet) < pumpDescription.extendedBolusStep) {
// correct extended already set
result.success(true).absolute(danaPump.extendedBolusAbsoluteRate).enacted(false).duration(danaPump.extendedBolusRemainingMinutes).isPercent(false).isTempCancel(false)
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Correct extended already set")
return result
}
// Now set new extended, no need to to stop previous (if running) because it's replaced
val extendedAmount = extendedRateToSet / 2 * durationInHalfHours
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Setting extended: " + extendedAmount + "U half hours: " + durationInHalfHours)
result = setExtendedBolus(extendedAmount, durationInMinutes)
if (!result.success) {
aapsLogger.error("setTempBasalAbsolute: Failed to set extended bolus")
return result
}
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Extended bolus set ok")
result.absolute(result.absolute + baseBasalRate)
return result
}
// We should never end here
aapsLogger.error("setTempBasalAbsolute: Internal error")
result.success(false).comment("Internal error")
return result
}
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
if (danaPump.isTempBasalInProgress) return cancelRealTempBasal()
if (danaPump.isExtendedInProgress && useExtendedBoluses) {
return cancelExtendedBolus()
}
val result = PumpEnactResult(injector)
result.success(true).enacted(false).comment(R.string.ok).isTempCancel(true)
return result
}
override fun model(): PumpType = PumpType.DANA_R_KOREAN
private fun cancelRealTempBasal(): PumpEnactResult {
val result = PumpEnactResult(injector)
if (danaPump.isTempBasalInProgress) {
sExecutionService.tempBasalStop()
if (!danaPump.isTempBasalInProgress) {
pumpSync.syncStopTemporaryBasalWithPumpId(
dateUtil._now(),
dateUtil._now(),
pumpDescription.pumpType,
serialNumber()
)
result.success(true).enacted(true).isTempCancel(true)
} else result.success(false).enacted(false).isTempCancel(true)
} else {
result.success(true).isTempCancel(true).comment(R.string.ok)
aapsLogger.debug(LTag.PUMP, "cancelRealTempBasal: OK")
}
return result
}
override fun loadEvents(): PumpEnactResult = PumpEnactResult(injector) // no history, not needed
override fun setUserOptions(): PumpEnactResult = PumpEnactResult(injector)
}