- more kotlinize, MedtronicHistoryActivity not yet working
This commit is contained in:
parent
a202178426
commit
6b7efdcb95
16 changed files with 2016 additions and 2615 deletions
|
@ -111,7 +111,7 @@ android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
versionCode 1500
|
versionCode 1500
|
||||||
version "2.8.2.1-dev-e3"
|
version "2.8.2.1-meallink-mdt"
|
||||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||||
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||||
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
|
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
|
||||||
|
|
|
@ -1,529 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.common;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.ServiceConnection;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
|
||||||
import info.nightscout.androidaps.core.R;
|
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
|
||||||
import info.nightscout.androidaps.data.Profile;
|
|
||||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
|
||||||
import info.nightscout.androidaps.events.EventAppExit;
|
|
||||||
import info.nightscout.androidaps.events.EventCustomActionsChanged;
|
|
||||||
import info.nightscout.androidaps.extensions.PumpStateExtensionKt;
|
|
||||||
import info.nightscout.androidaps.interfaces.ActivePlugin;
|
|
||||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider;
|
|
||||||
import info.nightscout.androidaps.interfaces.Constraints;
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
|
||||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
|
||||||
import info.nightscout.androidaps.interfaces.Pump;
|
|
||||||
import info.nightscout.androidaps.interfaces.PumpPluginBase;
|
|
||||||
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.common.ManufacturerType;
|
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.data.PumpDbEntry;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst;
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
|
||||||
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;
|
|
||||||
|
|
||||||
import static info.nightscout.androidaps.extensions.PumpStateExtensionKt.convertedToAbsolute;
|
|
||||||
import static info.nightscout.androidaps.extensions.PumpStateExtensionKt.getPlannedRemainingMinutes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by andy on 23.04.18.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// When using this class, make sure that your first step is to create mConnection (see MedtronicPumpPlugin)
|
|
||||||
|
|
||||||
public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump, Constraints {
|
|
||||||
private final CompositeDisposable disposable = new CompositeDisposable();
|
|
||||||
|
|
||||||
protected HasAndroidInjector injector;
|
|
||||||
protected AAPSLogger aapsLogger;
|
|
||||||
protected RxBusWrapper rxBus;
|
|
||||||
protected ActivePlugin activePlugin;
|
|
||||||
protected Context context;
|
|
||||||
protected FabricPrivacy fabricPrivacy;
|
|
||||||
protected ResourceHelper resourceHelper;
|
|
||||||
protected CommandQueueProvider commandQueue;
|
|
||||||
protected SP sp;
|
|
||||||
protected DateUtil dateUtil;
|
|
||||||
protected PumpDescription pumpDescription = new PumpDescription();
|
|
||||||
protected ServiceConnection serviceConnection;
|
|
||||||
protected boolean serviceRunning = false;
|
|
||||||
protected PumpDriverState pumpState = PumpDriverState.NotInitialized;
|
|
||||||
protected boolean displayConnectionMessages = false;
|
|
||||||
protected PumpType pumpType;
|
|
||||||
protected AapsSchedulers aapsSchedulers;
|
|
||||||
protected PumpSync pumpSync;
|
|
||||||
protected Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
|
|
||||||
|
|
||||||
protected PumpPluginAbstract(
|
|
||||||
PluginDescription pluginDescription,
|
|
||||||
PumpType pumpType,
|
|
||||||
HasAndroidInjector injector,
|
|
||||||
ResourceHelper resourceHelper,
|
|
||||||
AAPSLogger aapsLogger,
|
|
||||||
CommandQueueProvider commandQueue,
|
|
||||||
RxBusWrapper rxBus,
|
|
||||||
ActivePlugin activePlugin,
|
|
||||||
SP sp,
|
|
||||||
Context context,
|
|
||||||
FabricPrivacy fabricPrivacy,
|
|
||||||
DateUtil dateUtil,
|
|
||||||
AapsSchedulers aapsSchedulers,
|
|
||||||
PumpSync pumpSync
|
|
||||||
) {
|
|
||||||
|
|
||||||
super(pluginDescription, injector, aapsLogger, resourceHelper, commandQueue);
|
|
||||||
this.aapsLogger = aapsLogger;
|
|
||||||
this.rxBus = rxBus;
|
|
||||||
this.activePlugin = activePlugin;
|
|
||||||
this.context = context;
|
|
||||||
this.fabricPrivacy = fabricPrivacy;
|
|
||||||
this.resourceHelper = resourceHelper;
|
|
||||||
this.sp = sp;
|
|
||||||
this.commandQueue = commandQueue;
|
|
||||||
|
|
||||||
pumpDescription.setPumpDescription(pumpType);
|
|
||||||
this.pumpType = pumpType;
|
|
||||||
this.dateUtil = dateUtil;
|
|
||||||
this.aapsSchedulers = aapsSchedulers;
|
|
||||||
this.pumpSync = pumpSync;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public abstract void initPumpStatusData();
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
initPumpStatusData();
|
|
||||||
|
|
||||||
Intent intent = new Intent(context, getServiceClass());
|
|
||||||
context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
|
|
||||||
|
|
||||||
serviceRunning = true;
|
|
||||||
|
|
||||||
disposable.add(rxBus
|
|
||||||
.toObservable(EventAppExit.class)
|
|
||||||
.observeOn(aapsSchedulers.getIo())
|
|
||||||
.subscribe(event -> context.unbindService(serviceConnection), fabricPrivacy::logException)
|
|
||||||
);
|
|
||||||
onStartCustomActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
aapsLogger.debug(LTag.PUMP, this.deviceID() + " onStop()");
|
|
||||||
|
|
||||||
context.unbindService(serviceConnection);
|
|
||||||
|
|
||||||
serviceRunning = false;
|
|
||||||
|
|
||||||
disposable.clear();
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we need to run any custom actions in onStart (triggering events, etc)
|
|
||||||
*/
|
|
||||||
public abstract void onStartCustomActions();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service class (same one you did serviceConnection for)
|
|
||||||
*
|
|
||||||
* @return Class
|
|
||||||
*/
|
|
||||||
public abstract Class getServiceClass();
|
|
||||||
|
|
||||||
public abstract PumpStatus getPumpStatusData();
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isInitialized() {
|
|
||||||
return pumpState.isInitialized();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isSuspended() {
|
|
||||||
return pumpState == PumpDriverState.Suspended;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isBusy() {
|
|
||||||
return pumpState == PumpDriverState.Busy;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isConnected() {
|
|
||||||
if (displayConnectionMessages)
|
|
||||||
aapsLogger.debug(LTag.PUMP, "isConnected [PumpPluginAbstract].");
|
|
||||||
return pumpState.isConnected();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isConnecting() {
|
|
||||||
if (displayConnectionMessages)
|
|
||||||
aapsLogger.debug(LTag.PUMP, "isConnecting [PumpPluginAbstract].");
|
|
||||||
return pumpState == PumpDriverState.Connecting;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void connect(@NonNull String reason) {
|
|
||||||
if (displayConnectionMessages)
|
|
||||||
aapsLogger.debug(LTag.PUMP, "connect (reason={}) [PumpPluginAbstract] - default (empty) implementation." + reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void disconnect(@NonNull String reason) {
|
|
||||||
if (displayConnectionMessages)
|
|
||||||
aapsLogger.debug(LTag.PUMP, "disconnect (reason={}) [PumpPluginAbstract] - default (empty) implementation." + reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void stopConnecting() {
|
|
||||||
if (displayConnectionMessages)
|
|
||||||
aapsLogger.debug(LTag.PUMP, "stopConnecting [PumpPluginAbstract] - default (empty) implementation.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isHandshakeInProgress() {
|
|
||||||
if (displayConnectionMessages)
|
|
||||||
aapsLogger.debug(LTag.PUMP, "isHandshakeInProgress [PumpPluginAbstract] - default (empty) implementation.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void finishHandshaking() {
|
|
||||||
if (displayConnectionMessages)
|
|
||||||
aapsLogger.debug(LTag.PUMP, "finishHandshaking [PumpPluginAbstract] - default (empty) implementation.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload to pump new basal profile
|
|
||||||
@NonNull public PumpEnactResult setNewBasalProfile(@NonNull Profile profile) {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "setNewBasalProfile [PumpPluginAbstract] - Not implemented.");
|
|
||||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isThisProfileSet(@NonNull Profile profile) {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "isThisProfileSet [PumpPluginAbstract] - Not implemented.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public long lastDataTime() {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "lastDataTime [PumpPluginAbstract].");
|
|
||||||
return getPumpStatusData().getLastConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public double getBaseBasalRate() {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "getBaseBasalRate [PumpPluginAbstract] - Not implemented.");
|
|
||||||
return 0.0d;
|
|
||||||
} // base basal rate, not temp basal
|
|
||||||
|
|
||||||
|
|
||||||
public void stopBolusDelivering() {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "stopBolusDelivering [PumpPluginAbstract] - Not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull @Override
|
|
||||||
public PumpEnactResult setTempBasalAbsolute(double absoluteRate, int durationInMinutes, @NonNull Profile profile, boolean enforceNew, @NonNull PumpSync.TemporaryBasalType tbrType) {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute [PumpPluginAbstract] - Not implemented.");
|
|
||||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull @Override
|
|
||||||
public PumpEnactResult setTempBasalPercent(int percent, int durationInMinutes, @NonNull Profile profile, boolean enforceNew, @NonNull PumpSync.TemporaryBasalType tbrType) {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "setTempBasalPercent [PumpPluginAbstract] - Not implemented.");
|
|
||||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull public PumpEnactResult setExtendedBolus(double insulin, int durationInMinutes) {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "setExtendedBolus [PumpPluginAbstract] - Not implemented.");
|
|
||||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// some pumps might set a very short temp close to 100% as cancelling a temp can be noisy
|
|
||||||
// when the cancel request is requested by the user (forced), the pump should always do a real cancel
|
|
||||||
|
|
||||||
@NonNull public PumpEnactResult cancelTempBasal(boolean enforceNew) {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "cancelTempBasal [PumpPluginAbstract] - Not implemented.");
|
|
||||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull public PumpEnactResult cancelExtendedBolus() {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "cancelExtendedBolus [PumpPluginAbstract] - Not implemented.");
|
|
||||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Status to be passed to NS
|
|
||||||
|
|
||||||
// public JSONObject getJSONStatus(Profile profile, String profileName) {
|
|
||||||
// return pumpDriver.getJSONStatus(profile, profileName);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public String deviceID() {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "deviceID [PumpPluginAbstract] - Not implemented.");
|
|
||||||
return "FakeDevice";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Pump capabilities
|
|
||||||
|
|
||||||
|
|
||||||
public PumpDescription getPumpDescription() {
|
|
||||||
return pumpDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Short info for SMS, Wear etc
|
|
||||||
|
|
||||||
public boolean isFakingTempsByExtendedBoluses() {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "isFakingTempsByExtendedBoluses [PumpPluginAbstract] - Not implemented.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull @Override
|
|
||||||
public PumpEnactResult loadTDDs() {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "loadTDDs [PumpPluginAbstract] - Not implemented.");
|
|
||||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull @Override
|
|
||||||
public JSONObject getJSONStatus(@NonNull Profile profile, @NonNull String profileName, @NonNull String version) {
|
|
||||||
|
|
||||||
if ((getPumpStatusData().getLastConnection() + 60 * 60 * 1000L) < System.currentTimeMillis()) {
|
|
||||||
return new JSONObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
JSONObject pump = new JSONObject();
|
|
||||||
JSONObject battery = new JSONObject();
|
|
||||||
JSONObject status = new JSONObject();
|
|
||||||
JSONObject extended = new JSONObject();
|
|
||||||
try {
|
|
||||||
battery.put("percent", getPumpStatusData().getBatteryRemaining());
|
|
||||||
status.put("status", getPumpStatusData().getPumpStatusType() != null ? getPumpStatusData().getPumpStatusType().getStatus() : "normal");
|
|
||||||
extended.put("Version", version);
|
|
||||||
try {
|
|
||||||
extended.put("ActiveProfile", profileName);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PumpSync.PumpState.TemporaryBasal tb = pumpSync.expectedPumpState().getTemporaryBasal();
|
|
||||||
if (tb != null) {
|
|
||||||
extended.put("TempBasalAbsoluteRate", convertedToAbsolute(tb, now, profile));
|
|
||||||
extended.put("TempBasalStart", dateUtil.dateAndTimeString(tb.getTimestamp()));
|
|
||||||
extended.put("TempBasalRemaining", getPlannedRemainingMinutes(tb));
|
|
||||||
}
|
|
||||||
|
|
||||||
PumpSync.PumpState.ExtendedBolus eb = pumpSync.expectedPumpState().getExtendedBolus();
|
|
||||||
if (eb != null) {
|
|
||||||
extended.put("ExtendedBolusAbsoluteRate", eb.getRate());
|
|
||||||
extended.put("ExtendedBolusStart", dateUtil.dateAndTimeString(eb.getTimestamp()));
|
|
||||||
extended.put("ExtendedBolusRemaining", getPlannedRemainingMinutes(eb));
|
|
||||||
}
|
|
||||||
|
|
||||||
status.put("timestamp", dateUtil.toISOString(dateUtil.now()));
|
|
||||||
|
|
||||||
pump.put("battery", battery);
|
|
||||||
pump.put("status", status);
|
|
||||||
pump.put("extended", extended);
|
|
||||||
pump.put("reservoir", getPumpStatusData().getReservoirRemainingUnits());
|
|
||||||
pump.put("clock", dateUtil.toISOString(dateUtil.now()));
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return pump;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FIXME i18n, null checks: iob, TDD
|
|
||||||
@NonNull @Override
|
|
||||||
public String shortStatus(boolean veryShort) {
|
|
||||||
String ret = "";
|
|
||||||
if (getPumpStatusData().getLastConnection() != 0) {
|
|
||||||
long agoMsec = System.currentTimeMillis() - getPumpStatusData().getLastConnection();
|
|
||||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
|
||||||
ret += "LastConn: " + agoMin + " min ago\n";
|
|
||||||
}
|
|
||||||
if (getPumpStatusData().getLastBolusTime() != null && getPumpStatusData().getLastBolusTime().getTime() != 0) {
|
|
||||||
ret += "LastBolus: " + DecimalFormatter.INSTANCE.to2Decimal(getPumpStatusData().getLastBolusAmount()) + "U @" + //
|
|
||||||
android.text.format.DateFormat.format("HH:mm", getPumpStatusData().getLastBolusTime()) + "\n";
|
|
||||||
}
|
|
||||||
PumpSync.PumpState.TemporaryBasal activeTemp = pumpSync.expectedPumpState().getTemporaryBasal();
|
|
||||||
if (activeTemp != null) {
|
|
||||||
ret += "Temp: " + PumpStateExtensionKt.toStringFull(activeTemp, dateUtil) + "\n";
|
|
||||||
}
|
|
||||||
PumpSync.PumpState.ExtendedBolus activeExtendedBolus = pumpSync.expectedPumpState().getExtendedBolus();
|
|
||||||
if (activeExtendedBolus != null) {
|
|
||||||
ret += "Extended: " + PumpStateExtensionKt.toStringFull(activeExtendedBolus, dateUtil) + "\n";
|
|
||||||
}
|
|
||||||
// if (!veryShort) {
|
|
||||||
// ret += "TDD: " + DecimalFormatter.to0Decimal(pumpStatus.dailyTotalUnits) + " / "
|
|
||||||
// + pumpStatus.maxDailyTotalUnits + " U\n";
|
|
||||||
// }
|
|
||||||
ret += "IOB: " + getPumpStatusData().getIob() + "U\n";
|
|
||||||
ret += "Reserv: " + DecimalFormatter.INSTANCE.to0Decimal(getPumpStatusData().getReservoirRemainingUnits()) + "U\n";
|
|
||||||
ret += "Batt: " + getPumpStatusData().getBatteryRemaining() + "\n";
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull @Override
|
|
||||||
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (detailedBolusInfo.insulin == 0 && detailedBolusInfo.carbs == 0) {
|
|
||||||
// neither carbs nor bolus requested
|
|
||||||
aapsLogger.error("deliverTreatment: Invalid input");
|
|
||||||
return new PumpEnactResult(getInjector()).success(false).enacted(false).bolusDelivered(0d).carbsDelivered(0d)
|
|
||||||
.comment(R.string.invalidinput);
|
|
||||||
} else if (detailedBolusInfo.insulin > 0) {
|
|
||||||
// bolus needed, ask pump to deliver it
|
|
||||||
return deliverBolus(detailedBolusInfo);
|
|
||||||
} else {
|
|
||||||
//if (MedtronicHistoryData.doubleBolusDebug)
|
|
||||||
// aapsLogger.debug("DoubleBolusDebug: deliverTreatment::(carb only entry)");
|
|
||||||
|
|
||||||
// TODO fix
|
|
||||||
// no bolus required, carb only treatment
|
|
||||||
activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, true);
|
|
||||||
|
|
||||||
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE;
|
|
||||||
bolusingEvent.setT(new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB));
|
|
||||||
bolusingEvent.setPercent(100);
|
|
||||||
rxBus.send(bolusingEvent);
|
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMP, "deliverTreatment: Carb only treatment.");
|
|
||||||
|
|
||||||
return new PumpEnactResult(getInjector()).success(true).enacted(true).bolusDelivered(0d)
|
|
||||||
.carbsDelivered(detailedBolusInfo.carbs).comment(R.string.common_resultok);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
triggerUIChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void refreshCustomActionsList() {
|
|
||||||
rxBus.send(new EventCustomActionsChanged());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull public ManufacturerType manufacturer() {
|
|
||||||
return pumpType.getManufacturer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public PumpType model() {
|
|
||||||
return pumpType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public PumpType getPumpType() {
|
|
||||||
return pumpType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setPumpType(PumpType pumpType) {
|
|
||||||
this.pumpType = pumpType;
|
|
||||||
this.pumpDescription.setPumpDescription(pumpType);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean canHandleDST() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected abstract PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo);
|
|
||||||
|
|
||||||
protected abstract void triggerUIChange();
|
|
||||||
|
|
||||||
private PumpEnactResult getOperationNotSupportedWithCustomText(int resourceId) {
|
|
||||||
return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(resourceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PumpSync
|
|
||||||
|
|
||||||
Map<Long, PumpDbEntry> driverHistory = new HashMap<>();
|
|
||||||
|
|
||||||
public abstract long generateTempId(long timeMillis);
|
|
||||||
|
|
||||||
protected boolean addBolusWithTempId(DetailedBolusInfo detailedBolusInfo, boolean writeToInternalHistory) {
|
|
||||||
long temporaryId = generateTempId(detailedBolusInfo.timestamp);
|
|
||||||
boolean response = pumpSync.addBolusWithTempId(detailedBolusInfo.timestamp, detailedBolusInfo.insulin,
|
|
||||||
temporaryId, detailedBolusInfo.getBolusType(),
|
|
||||||
getPumpType(), serialNumber());
|
|
||||||
|
|
||||||
if (response && writeToInternalHistory) {
|
|
||||||
driverHistory.put(temporaryId, new PumpDbEntry(temporaryId, model(), serialNumber(), detailedBolusInfo));
|
|
||||||
sp.putString(MedtronicConst.Statistics.InternalTemporaryDatabase, gson.toJson(driverHistory));
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void addTemporaryBasalRateWithTempId(TemporaryBasal temporaryBasal, boolean b) {
|
|
||||||
// long temporaryId = generateTempId(temporaryBasal.timestamp);
|
|
||||||
// boolean response = pumpSync.addBolusWithTempId(temporaryBasal.timestamp, detailedBolusInfo.insulin,
|
|
||||||
// generateTempId(detailedBolusInfo.timestamp), detailedBolusInfo.getBolusType(),
|
|
||||||
// getPumpType(), serialNumber());
|
|
||||||
//
|
|
||||||
// if (response && writeToInternalHistory) {
|
|
||||||
// driverHistory.put(temporaryId, new PumpDbEntry(temporaryId, model(), serialNumber(), detailedBolusInfo));
|
|
||||||
// sp.putString(MedtronicConst.Statistics.InternalTemporaryDatabase, gson.toJson(driverHistory));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void removeTemporaryId(long temporaryId) {
|
|
||||||
driverHistory.remove(temporaryId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,431 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.common
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.ServiceConnection
|
||||||
|
import android.text.format.DateFormat
|
||||||
|
import com.google.gson.GsonBuilder
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.core.R
|
||||||
|
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||||
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
import info.nightscout.androidaps.data.PumpEnactResult
|
||||||
|
import info.nightscout.androidaps.db.TemporaryBasal
|
||||||
|
import info.nightscout.androidaps.events.EventAppExit
|
||||||
|
import info.nightscout.androidaps.events.EventCustomActionsChanged
|
||||||
|
import info.nightscout.androidaps.extensions.convertedToAbsolute
|
||||||
|
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
|
||||||
|
import info.nightscout.androidaps.extensions.toStringFull
|
||||||
|
import info.nightscout.androidaps.interfaces.*
|
||||||
|
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.common.ManufacturerType
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.data.PumpDbEntry
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||||
|
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.DecimalFormatter.to0Decimal
|
||||||
|
import info.nightscout.androidaps.utils.DecimalFormatter.to2Decimal
|
||||||
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
|
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
|
||||||
|
import org.json.JSONException
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by andy on 23.04.18.
|
||||||
|
*/
|
||||||
|
// When using this class, make sure that your first step is to create mConnection (see MedtronicPumpPlugin)
|
||||||
|
abstract class PumpPluginAbstract protected constructor(
|
||||||
|
pluginDescription: PluginDescription?,
|
||||||
|
pumpType: PumpType,
|
||||||
|
injector: HasAndroidInjector?,
|
||||||
|
resourceHelper: ResourceHelper,
|
||||||
|
aapsLogger: AAPSLogger,
|
||||||
|
commandQueue: CommandQueueProvider,
|
||||||
|
var rxBus: RxBusWrapper,
|
||||||
|
var activePlugin: ActivePlugin,
|
||||||
|
var sp: SP,
|
||||||
|
var context: Context,
|
||||||
|
var fabricPrivacy: FabricPrivacy,
|
||||||
|
dateUtil: DateUtil,
|
||||||
|
aapsSchedulers: AapsSchedulers,
|
||||||
|
pumpSync: PumpSync
|
||||||
|
) : PumpPluginBase(pluginDescription!!, injector!!, aapsLogger, resourceHelper, commandQueue), Pump, Constraints {
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
//protected override var injector: HasAndroidInjector? = null
|
||||||
|
protected var dateUtil: DateUtil
|
||||||
|
|
||||||
|
// Pump capabilities
|
||||||
|
final override var pumpDescription = PumpDescription()
|
||||||
|
//protected set
|
||||||
|
|
||||||
|
@JvmField protected var serviceConnection: ServiceConnection? = null
|
||||||
|
@JvmField protected var serviceRunning = false
|
||||||
|
@JvmField protected var pumpState = PumpDriverState.NotInitialized
|
||||||
|
@JvmField protected var displayConnectionMessages = false
|
||||||
|
|
||||||
|
var pumpType: PumpType? = null
|
||||||
|
get() = field
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
pumpDescription.setPumpDescription(value!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected var aapsSchedulers: AapsSchedulers
|
||||||
|
protected var pumpSync: PumpSync
|
||||||
|
protected var gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
|
||||||
|
|
||||||
|
abstract fun initPumpStatusData()
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
initPumpStatusData()
|
||||||
|
val intent = Intent(context, serviceClass)
|
||||||
|
context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
|
||||||
|
serviceRunning = true
|
||||||
|
disposable.add(rxBus
|
||||||
|
.toObservable(EventAppExit::class.java)
|
||||||
|
.observeOn(aapsSchedulers.io)
|
||||||
|
.subscribe({ event: EventAppExit? -> context.unbindService(serviceConnection) }) { throwable: Throwable? -> fabricPrivacy.logException(throwable!!) }
|
||||||
|
)
|
||||||
|
onStartCustomActions()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
aapsLogger.debug(LTag.PUMP, deviceID() + " onStop()")
|
||||||
|
context.unbindService(serviceConnection)
|
||||||
|
serviceRunning = false
|
||||||
|
disposable.clear()
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we need to run any custom actions in onStart (triggering events, etc)
|
||||||
|
*/
|
||||||
|
abstract fun onStartCustomActions()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service class (same one you did serviceConnection for)
|
||||||
|
*
|
||||||
|
* @return Class
|
||||||
|
*/
|
||||||
|
abstract val serviceClass: Class<*>?
|
||||||
|
abstract val pumpStatusData: PumpStatus
|
||||||
|
|
||||||
|
override fun isInitialized(): Boolean {
|
||||||
|
return pumpState.isInitialized()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isSuspended(): Boolean {
|
||||||
|
return pumpState === PumpDriverState.Suspended
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isBusy(): Boolean {
|
||||||
|
return pumpState === PumpDriverState.Busy
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isConnected(): Boolean {
|
||||||
|
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "isConnected [PumpPluginAbstract].")
|
||||||
|
return pumpState.isConnected()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isConnecting(): Boolean {
|
||||||
|
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "isConnecting [PumpPluginAbstract].")
|
||||||
|
return pumpState === PumpDriverState.Connecting
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun connect(reason: String) {
|
||||||
|
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "connect (reason={}) [PumpPluginAbstract] - default (empty) implementation.$reason")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun disconnect(reason: String) {
|
||||||
|
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "disconnect (reason={}) [PumpPluginAbstract] - default (empty) implementation.$reason")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stopConnecting() {
|
||||||
|
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "stopConnecting [PumpPluginAbstract] - default (empty) implementation.")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isHandshakeInProgress(): Boolean {
|
||||||
|
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "isHandshakeInProgress [PumpPluginAbstract] - default (empty) implementation.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun finishHandshaking() {
|
||||||
|
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "finishHandshaking [PumpPluginAbstract] - default (empty) implementation.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload to pump new basal profile
|
||||||
|
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "setNewBasalProfile [PumpPluginAbstract] - Not implemented.")
|
||||||
|
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isThisProfileSet(profile: Profile): Boolean {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "isThisProfileSet [PumpPluginAbstract] - Not implemented.")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun lastDataTime(): Long {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "lastDataTime [PumpPluginAbstract].")
|
||||||
|
return pumpStatusData.lastConnection
|
||||||
|
}
|
||||||
|
|
||||||
|
// base basal rate, not temp basal
|
||||||
|
override val baseBasalRate: Double
|
||||||
|
get() {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "getBaseBasalRate [PumpPluginAbstract] - Not implemented.")
|
||||||
|
return 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stopBolusDelivering() {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "stopBolusDelivering [PumpPluginAbstract] - Not implemented.")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: TemporaryBasalType): PumpEnactResult {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute [PumpPluginAbstract] - Not implemented.")
|
||||||
|
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: TemporaryBasalType): PumpEnactResult {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "setTempBasalPercent [PumpPluginAbstract] - Not implemented.")
|
||||||
|
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "setExtendedBolus [PumpPluginAbstract] - Not implemented.")
|
||||||
|
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
// some pumps might set a very short temp close to 100% as cancelling a temp can be noisy
|
||||||
|
// when the cancel request is requested by the user (forced), the pump should always do a real cancel
|
||||||
|
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "cancelTempBasal [PumpPluginAbstract] - Not implemented.")
|
||||||
|
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun cancelExtendedBolus(): PumpEnactResult {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "cancelExtendedBolus [PumpPluginAbstract] - Not implemented.")
|
||||||
|
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status to be passed to NS
|
||||||
|
// public JSONObject getJSONStatus(Profile profile, String profileName) {
|
||||||
|
// return pumpDriver.getJSONStatus(profile, profileName);
|
||||||
|
// }
|
||||||
|
open fun deviceID(): String {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "deviceID [PumpPluginAbstract] - Not implemented.")
|
||||||
|
return "FakeDevice"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Short info for SMS, Wear etc
|
||||||
|
override val isFakingTempsByExtendedBoluses: Boolean
|
||||||
|
get() {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "isFakingTempsByExtendedBoluses [PumpPluginAbstract] - Not implemented.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadTDDs(): PumpEnactResult {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "loadTDDs [PumpPluginAbstract] - Not implemented.")
|
||||||
|
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject {
|
||||||
|
if (pumpStatusData.lastConnection + 60 * 60 * 1000L < System.currentTimeMillis()) {
|
||||||
|
return JSONObject()
|
||||||
|
}
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
val pump = JSONObject()
|
||||||
|
val battery = JSONObject()
|
||||||
|
val status = JSONObject()
|
||||||
|
val extended = JSONObject()
|
||||||
|
try {
|
||||||
|
battery.put("percent", pumpStatusData.batteryRemaining)
|
||||||
|
status.put("status", if (pumpStatusData.pumpStatusType != null) pumpStatusData.pumpStatusType.status else "normal")
|
||||||
|
extended.put("Version", version)
|
||||||
|
try {
|
||||||
|
extended.put("ActiveProfile", profileName)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
}
|
||||||
|
val tb = pumpSync.expectedPumpState().temporaryBasal
|
||||||
|
if (tb != null) {
|
||||||
|
extended.put("TempBasalAbsoluteRate", tb.convertedToAbsolute(now, profile))
|
||||||
|
extended.put("TempBasalStart", dateUtil.dateAndTimeString(tb.timestamp))
|
||||||
|
extended.put("TempBasalRemaining", tb.plannedRemainingMinutes)
|
||||||
|
}
|
||||||
|
val eb = pumpSync.expectedPumpState().extendedBolus
|
||||||
|
if (eb != null) {
|
||||||
|
extended.put("ExtendedBolusAbsoluteRate", eb.rate)
|
||||||
|
extended.put("ExtendedBolusStart", dateUtil.dateAndTimeString(eb.timestamp))
|
||||||
|
extended.put("ExtendedBolusRemaining", eb.plannedRemainingMinutes)
|
||||||
|
}
|
||||||
|
status.put("timestamp", dateUtil.toISOString(dateUtil.now()))
|
||||||
|
pump.put("battery", battery)
|
||||||
|
pump.put("status", status)
|
||||||
|
pump.put("extended", extended)
|
||||||
|
pump.put("reservoir", pumpStatusData.reservoirRemainingUnits)
|
||||||
|
pump.put("clock", dateUtil.toISOString(dateUtil.now()))
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
aapsLogger.error("Unhandled exception", e)
|
||||||
|
}
|
||||||
|
return pump
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME i18n, null checks: iob, TDD
|
||||||
|
override fun shortStatus(veryShort: Boolean): String {
|
||||||
|
var ret = ""
|
||||||
|
|
||||||
|
if (pumpStatusData.lastConnection==0L) {
|
||||||
|
ret += "LastConn: never\n"
|
||||||
|
} else {
|
||||||
|
val agoMsec = System.currentTimeMillis() - pumpStatusData.lastConnection
|
||||||
|
val agoMin = (agoMsec / 60.0 / 1000.0).toInt()
|
||||||
|
ret += "LastConn: $agoMin min ago\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pumpStatusData.lastBolusTime != null && pumpStatusData.lastBolusTime!!.time != 0L) {
|
||||||
|
ret += """
|
||||||
|
LastBolus: ${to2Decimal(pumpStatusData.lastBolusAmount!!)}U @${DateFormat.format("HH:mm", pumpStatusData.lastBolusTime)}
|
||||||
|
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
val activeTemp = pumpSync.expectedPumpState().temporaryBasal
|
||||||
|
if (activeTemp != null) {
|
||||||
|
ret += """
|
||||||
|
Temp: ${activeTemp.toStringFull(dateUtil)}
|
||||||
|
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
val activeExtendedBolus = pumpSync.expectedPumpState().extendedBolus
|
||||||
|
if (activeExtendedBolus != null) {
|
||||||
|
ret += """
|
||||||
|
Extended: ${activeExtendedBolus.toStringFull(dateUtil)}
|
||||||
|
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
// if (!veryShort) {
|
||||||
|
// ret += "TDD: " + DecimalFormatter.to0Decimal(pumpStatus.dailyTotalUnits) + " / "
|
||||||
|
// + pumpStatus.maxDailyTotalUnits + " U\n";
|
||||||
|
// }
|
||||||
|
ret += """
|
||||||
|
IOB: ${pumpStatusData.iob}U
|
||||||
|
|
||||||
|
""".trimIndent()
|
||||||
|
ret += """
|
||||||
|
Reserv: ${to0Decimal(pumpStatusData.reservoirRemainingUnits)}U
|
||||||
|
|
||||||
|
""".trimIndent()
|
||||||
|
ret += """
|
||||||
|
Batt: ${pumpStatusData.batteryRemaining}
|
||||||
|
|
||||||
|
""".trimIndent()
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
|
||||||
|
return try {
|
||||||
|
if (detailedBolusInfo.insulin == 0.0 && detailedBolusInfo.carbs == 0.0) {
|
||||||
|
// neither carbs nor bolus requested
|
||||||
|
aapsLogger.error("deliverTreatment: Invalid input")
|
||||||
|
PumpEnactResult(injector).success(false).enacted(false).bolusDelivered(0.0).carbsDelivered(0.0)
|
||||||
|
.comment(R.string.invalidinput)
|
||||||
|
} else if (detailedBolusInfo.insulin > 0) {
|
||||||
|
// bolus needed, ask pump to deliver it
|
||||||
|
deliverBolus(detailedBolusInfo)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// TODO fix
|
||||||
|
// no bolus required, carb only treatment
|
||||||
|
activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, true)
|
||||||
|
val bolusingEvent = EventOverviewBolusProgress
|
||||||
|
bolusingEvent.t = EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.bolusType === DetailedBolusInfo.BolusType.SMB)
|
||||||
|
bolusingEvent.percent = 100
|
||||||
|
rxBus.send(bolusingEvent)
|
||||||
|
aapsLogger.debug(LTag.PUMP, "deliverTreatment: Carb only treatment.")
|
||||||
|
PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(0.0)
|
||||||
|
.carbsDelivered(detailedBolusInfo.carbs).comment(R.string.common_resultok)
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
triggerUIChange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun refreshCustomActionsList() {
|
||||||
|
rxBus.send(EventCustomActionsChanged())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun manufacturer(): ManufacturerType {
|
||||||
|
return pumpType!!.manufacturer!!
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun model(): PumpType {
|
||||||
|
return pumpType!!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun canHandleDST(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun deliverBolus(detailedBolusInfo: DetailedBolusInfo?): PumpEnactResult
|
||||||
|
|
||||||
|
protected abstract fun triggerUIChange()
|
||||||
|
|
||||||
|
private fun getOperationNotSupportedWithCustomText(resourceId: Int): PumpEnactResult {
|
||||||
|
return PumpEnactResult(injector).success(false).enacted(false).comment(resourceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PumpSync
|
||||||
|
var driverHistory: MutableMap<Long, PumpDbEntry> = HashMap()
|
||||||
|
|
||||||
|
abstract fun generateTempId(timeMillis: Long): Long
|
||||||
|
|
||||||
|
protected fun addBolusWithTempId(detailedBolusInfo: DetailedBolusInfo, writeToInternalHistory: Boolean): Boolean {
|
||||||
|
val temporaryId = generateTempId(detailedBolusInfo.timestamp)
|
||||||
|
val response = pumpSync.addBolusWithTempId(detailedBolusInfo.timestamp, detailedBolusInfo.insulin,
|
||||||
|
temporaryId, detailedBolusInfo.bolusType,
|
||||||
|
pumpType!!, serialNumber())
|
||||||
|
if (response && writeToInternalHistory) {
|
||||||
|
driverHistory[temporaryId] = PumpDbEntry(temporaryId, model(), serialNumber(), detailedBolusInfo)
|
||||||
|
sp.putString(MedtronicConst.Statistics.InternalTemporaryDatabase, gson.toJson(driverHistory))
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun addTemporaryBasalRateWithTempId(temporaryBasal: TemporaryBasal?, b: Boolean) {
|
||||||
|
// long temporaryId = generateTempId(temporaryBasal.timestamp);
|
||||||
|
// boolean response = pumpSync.addBolusWithTempId(temporaryBasal.timestamp, detailedBolusInfo.insulin,
|
||||||
|
// generateTempId(detailedBolusInfo.timestamp), detailedBolusInfo.getBolusType(),
|
||||||
|
// getPumpType(), serialNumber());
|
||||||
|
//
|
||||||
|
// if (response && writeToInternalHistory) {
|
||||||
|
// driverHistory.put(temporaryId, new PumpDbEntry(temporaryId, model(), serialNumber(), detailedBolusInfo));
|
||||||
|
// sp.putString(MedtronicConst.Statistics.InternalTemporaryDatabase, gson.toJson(driverHistory));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeTemporaryId(temporaryId: Long) {
|
||||||
|
driverHistory.remove(temporaryId)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
pumpDescription.setPumpDescription(pumpType)
|
||||||
|
this.pumpType = pumpType
|
||||||
|
this.dateUtil = dateUtil
|
||||||
|
this.aapsSchedulers = aapsSchedulers
|
||||||
|
this.pumpSync = pumpSync
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.common.data;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
|
|
||||||
|
|
||||||
public class PumpDbEntry {
|
|
||||||
|
|
||||||
long temporaryId;
|
|
||||||
PumpType pumpType;
|
|
||||||
String serialNumber;
|
|
||||||
DetailedBolusInfo detailedBolusInfo;
|
|
||||||
|
|
||||||
public PumpDbEntry(long temporaryId, PumpType pumpType, String serialNumber, DetailedBolusInfo detailedBolusInfo) {
|
|
||||||
this.temporaryId = temporaryId;
|
|
||||||
this.pumpType = pumpType;
|
|
||||||
this.serialNumber = serialNumber;
|
|
||||||
this.detailedBolusInfo = detailedBolusInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.common.data
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||||
|
|
||||||
|
data class PumpDbEntry(var temporaryId: Long,
|
||||||
|
var pumpType: PumpType,
|
||||||
|
var serialNumber: String,
|
||||||
|
var detailedBolusInfo: DetailedBolusInfo)
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -599,6 +599,44 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private <T> T sendAndGetResponseWithCheck(MedtronicCommandType commandType, byte[] bodyData, Class<T> clazz) {
|
||||||
|
|
||||||
|
aapsLogger.debug(LTag.PUMPCOMM, "getDataFromPump: " + commandType);
|
||||||
|
|
||||||
|
for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
PumpMessage response = sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
|
||||||
|
|
||||||
|
String check = checkResponseContent(response, commandType.getCommandDescription(), commandType.getExpectedLength());
|
||||||
|
|
||||||
|
if (check == null) {
|
||||||
|
|
||||||
|
T dataResponse = (T)medtronicConverter.convertResponse(medtronicPumpPlugin.getPumpDescription().getPumpType(), commandType, response.getRawContent());
|
||||||
|
|
||||||
|
if (dataResponse != null) {
|
||||||
|
this.errorMessage = null;
|
||||||
|
aapsLogger.debug(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Converted response for %s is %s.", commandType.name(), dataResponse));
|
||||||
|
|
||||||
|
return dataResponse;
|
||||||
|
} else {
|
||||||
|
this.errorMessage = "Error decoding response.";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.errorMessage = check;
|
||||||
|
// return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (RileyLinkCommunicationException e) {
|
||||||
|
aapsLogger.warn(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Error getting response from RileyLink (error=%s, retry=%d)", e.getMessage(), retries + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private String checkResponseContent(PumpMessage response, String method, int expectedLength) {
|
private String checkResponseContent(PumpMessage response, String method, int expectedLength) {
|
||||||
|
|
||||||
if (!response.isValid()) {
|
if (!response.isValid()) {
|
||||||
|
|
|
@ -32,7 +32,8 @@ class BasalProfile {
|
||||||
|
|
||||||
private val aapsLogger: AAPSLogger
|
private val aapsLogger: AAPSLogger
|
||||||
|
|
||||||
@Expose var rawData : ByteArray? = null // store as byte array to make transport (via parcel) easier
|
@Expose
|
||||||
|
lateinit var rawData : ByteArray // store as byte array to make transport (via parcel) easier
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private var listEntries: MutableList<BasalProfileEntry>? = null
|
private var listEntries: MutableList<BasalProfileEntry>? = null
|
||||||
|
@ -48,14 +49,11 @@ class BasalProfile {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
rawData = ByteArray(MAX_RAW_DATA_SIZE)
|
rawData = byteArrayOf(0,0,0x3f)
|
||||||
rawData!![0] = 0
|
|
||||||
rawData!![1] = 0
|
|
||||||
rawData!![2] = 0x3f
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setRawData(data: ByteArray): Boolean {
|
private fun setRawData(data: ByteArray): Boolean {
|
||||||
var dataInternal: ByteArray? = data
|
var dataInternal: ByteArray = data
|
||||||
if (dataInternal == null) {
|
if (dataInternal == null) {
|
||||||
aapsLogger.error(LTag.PUMPCOMM, "setRawData: buffer is null!")
|
aapsLogger.error(LTag.PUMPCOMM, "setRawData: buffer is null!")
|
||||||
return false
|
return false
|
||||||
|
@ -81,17 +79,16 @@ class BasalProfile {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
rawData = ByteArray(MAX_RAW_DATA_SIZE)
|
rawData = ByteArray(MAX_RAW_DATA_SIZE)
|
||||||
val item = 0
|
|
||||||
var i = 0
|
var i = 0
|
||||||
while (i < data.size - 2) {
|
while (i < data.size - 2) {
|
||||||
if (data[i] == 0.toByte() && data[i + 1] == 0.toByte() && data[i + 2] == 0.toByte()) {
|
if (data[i] == 0.toByte() && data[i + 1] == 0.toByte() && data[i + 2] == 0.toByte()) {
|
||||||
rawData!![i] = 0
|
rawData[i] = 0
|
||||||
rawData!![i + 1] = 0
|
rawData[i + 1] = 0
|
||||||
rawData!![i + 2] = 0
|
rawData[i + 2] = 0
|
||||||
}
|
}
|
||||||
rawData!![i] = data[i + 1]
|
rawData[i] = data[i + 1]
|
||||||
rawData!![i + 1] = data[i + 2]
|
rawData[i + 1] = data[i + 2]
|
||||||
rawData!![i + 2] = data[i]
|
rawData[i + 2] = data[i]
|
||||||
i += 3
|
i += 3
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -306,7 +303,7 @@ class BasalProfile {
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getProfilesByHourToString(data: Array<Double?>): String {
|
fun getProfilesByHourToString(data: Array<Double>): String {
|
||||||
val stringBuilder = StringBuilder()
|
val stringBuilder = StringBuilder()
|
||||||
for (value in data) {
|
for (value in data) {
|
||||||
stringBuilder.append(String.format("%.3f", value))
|
stringBuilder.append(String.format("%.3f", value))
|
||||||
|
|
|
@ -1,250 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.medtronic.dialog;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.SystemClock;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Spinner;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.R;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData;
|
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
|
||||||
|
|
||||||
|
|
||||||
public class MedtronicHistoryActivity extends NoSplashAppCompatActivity {
|
|
||||||
|
|
||||||
@Inject MedtronicHistoryData medtronicHistoryData;
|
|
||||||
@Inject ResourceHelper resourceHelper;
|
|
||||||
|
|
||||||
Spinner historyTypeSpinner;
|
|
||||||
TextView statusView;
|
|
||||||
RecyclerView recyclerView;
|
|
||||||
LinearLayoutManager llm;
|
|
||||||
|
|
||||||
static TypeList showingType = null;
|
|
||||||
static PumpHistoryEntryGroup selectedGroup = PumpHistoryEntryGroup.All;
|
|
||||||
List<PumpHistoryEntry> filteredHistoryList = new ArrayList<>();
|
|
||||||
|
|
||||||
RecyclerViewAdapter recyclerViewAdapter;
|
|
||||||
boolean manualChange = false;
|
|
||||||
|
|
||||||
List<TypeList> typeListFull;
|
|
||||||
|
|
||||||
|
|
||||||
private void filterHistory(PumpHistoryEntryGroup group) {
|
|
||||||
|
|
||||||
this.filteredHistoryList.clear();
|
|
||||||
|
|
||||||
List<PumpHistoryEntry> list = new ArrayList<>();
|
|
||||||
list.addAll(medtronicHistoryData.getAllHistory());
|
|
||||||
|
|
||||||
//LOG.debug("Items on full list: {}", list.size());
|
|
||||||
|
|
||||||
if (group == PumpHistoryEntryGroup.All) {
|
|
||||||
this.filteredHistoryList.addAll(list);
|
|
||||||
} else {
|
|
||||||
for (PumpHistoryEntry pumpHistoryEntry : list) {
|
|
||||||
if (pumpHistoryEntry.getEntryType().getGroup() == group) {
|
|
||||||
this.filteredHistoryList.add(pumpHistoryEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.recyclerViewAdapter != null) {
|
|
||||||
this.recyclerViewAdapter.setHistoryList(this.filteredHistoryList);
|
|
||||||
this.recyclerViewAdapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
//LOG.debug("Items on filtered list: {}", filteredHistoryList.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
filterHistory(selectedGroup);
|
|
||||||
setHistoryTypeSpinner();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void setHistoryTypeSpinner() {
|
|
||||||
this.manualChange = true;
|
|
||||||
|
|
||||||
for (int i = 0; i < typeListFull.size(); i++) {
|
|
||||||
if (typeListFull.get(i).entryGroup == selectedGroup) {
|
|
||||||
historyTypeSpinner.setSelection(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemClock.sleep(200);
|
|
||||||
this.manualChange = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.medtronic_history_activity);
|
|
||||||
|
|
||||||
historyTypeSpinner = findViewById(R.id.medtronic_historytype);
|
|
||||||
statusView = findViewById(R.id.medtronic_historystatus);
|
|
||||||
recyclerView = findViewById(R.id.medtronic_history_recyclerview);
|
|
||||||
|
|
||||||
recyclerView.setHasFixedSize(true);
|
|
||||||
llm = new LinearLayoutManager(this);
|
|
||||||
recyclerView.setLayoutManager(llm);
|
|
||||||
|
|
||||||
recyclerViewAdapter = new RecyclerViewAdapter(filteredHistoryList);
|
|
||||||
recyclerView.setAdapter(recyclerViewAdapter);
|
|
||||||
|
|
||||||
statusView.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
typeListFull = getTypeList(PumpHistoryEntryGroup.getTranslatedList(resourceHelper));
|
|
||||||
|
|
||||||
ArrayAdapter<TypeList> spinnerAdapter = new ArrayAdapter<>(this, R.layout.spinner_centered, typeListFull);
|
|
||||||
historyTypeSpinner.setAdapter(spinnerAdapter);
|
|
||||||
|
|
||||||
historyTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
|
||||||
if (manualChange)
|
|
||||||
return;
|
|
||||||
TypeList selected = (TypeList) historyTypeSpinner.getSelectedItem();
|
|
||||||
showingType = selected;
|
|
||||||
selectedGroup = selected.entryGroup;
|
|
||||||
filterHistory(selectedGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNothingSelected(AdapterView<?> parent) {
|
|
||||||
if (manualChange)
|
|
||||||
return;
|
|
||||||
filterHistory(PumpHistoryEntryGroup.All);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private List<TypeList> getTypeList(List<PumpHistoryEntryGroup> list) {
|
|
||||||
|
|
||||||
ArrayList<TypeList> typeList = new ArrayList<>();
|
|
||||||
|
|
||||||
for (PumpHistoryEntryGroup pumpHistoryEntryGroup : list) {
|
|
||||||
typeList.add(new TypeList(pumpHistoryEntryGroup));
|
|
||||||
}
|
|
||||||
|
|
||||||
return typeList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TypeList {
|
|
||||||
|
|
||||||
PumpHistoryEntryGroup entryGroup;
|
|
||||||
String name;
|
|
||||||
|
|
||||||
|
|
||||||
TypeList(PumpHistoryEntryGroup entryGroup) {
|
|
||||||
this.entryGroup = entryGroup;
|
|
||||||
this.name = entryGroup.getTranslated();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.HistoryViewHolder> {
|
|
||||||
|
|
||||||
List<PumpHistoryEntry> historyList;
|
|
||||||
|
|
||||||
|
|
||||||
RecyclerViewAdapter(List<PumpHistoryEntry> historyList) {
|
|
||||||
this.historyList = historyList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setHistoryList(List<PumpHistoryEntry> historyList) {
|
|
||||||
// this.historyList.clear();
|
|
||||||
// this.historyList.addAll(historyList);
|
|
||||||
|
|
||||||
this.historyList = historyList;
|
|
||||||
|
|
||||||
// this.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HistoryViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
|
|
||||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.medtronic_history_item, //
|
|
||||||
viewGroup, false);
|
|
||||||
return new HistoryViewHolder(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(HistoryViewHolder holder, int position) {
|
|
||||||
PumpHistoryEntry record = historyList.get(position);
|
|
||||||
|
|
||||||
if (record != null) {
|
|
||||||
holder.timeView.setText(record.getDateTimeString());
|
|
||||||
holder.typeView.setText(record.getEntryType().getDescription());
|
|
||||||
holder.valueView.setText(record.getDisplayableValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return historyList.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
|
|
||||||
super.onAttachedToRecyclerView(recyclerView);
|
|
||||||
}
|
|
||||||
|
|
||||||
static class HistoryViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
TextView timeView;
|
|
||||||
TextView typeView;
|
|
||||||
TextView valueView;
|
|
||||||
|
|
||||||
|
|
||||||
HistoryViewHolder(View itemView) {
|
|
||||||
super(itemView);
|
|
||||||
// cv = (CardView)itemView.findViewById(R.id.rileylink_history_item);
|
|
||||||
timeView = itemView.findViewById(R.id.medtronic_history_time);
|
|
||||||
typeView = itemView.findViewById(R.id.medtronic_history_source);
|
|
||||||
valueView = itemView.findViewById(R.id.medtronic_history_description);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.medtronic.dialog
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.SystemClock
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.AdapterView
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import android.widget.Spinner
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import dagger.android.DaggerActivity
|
||||||
|
import dagger.android.DispatchingAndroidInjector
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup.Companion.getTranslatedList
|
||||||
|
import info.nightscout.androidaps.plugins.pump.medtronic.R
|
||||||
|
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry
|
||||||
|
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData
|
||||||
|
import info.nightscout.androidaps.plugins.pump.medtronic.databinding.MedtronicHistoryActivityBinding
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class MedtronicHistoryActivity : DaggerActivity() {
|
||||||
|
|
||||||
|
@Inject lateinit var medtronicHistoryData: MedtronicHistoryData
|
||||||
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
|
|
||||||
|
lateinit var historyTypeSpinner: Spinner
|
||||||
|
lateinit var statusView: TextView
|
||||||
|
lateinit var recyclerView: RecyclerView
|
||||||
|
lateinit var llm: LinearLayoutManager
|
||||||
|
lateinit var recyclerViewAdapter: RecyclerViewAdapter
|
||||||
|
|
||||||
|
var filteredHistoryList: MutableList<PumpHistoryEntry> = ArrayList()
|
||||||
|
var manualChange = false
|
||||||
|
var typeListFull: List<TypeList>? = null
|
||||||
|
|
||||||
|
private var _binding: MedtronicHistoryActivityBinding? = null
|
||||||
|
|
||||||
|
//@Inject
|
||||||
|
//var fragmentInjector: DispatchingAndroidInjector<Fragment>? = null
|
||||||
|
|
||||||
|
// This property is only valid between onCreateView and
|
||||||
|
// onDestroyView.
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
private fun filterHistory(group: PumpHistoryEntryGroup) {
|
||||||
|
filteredHistoryList.clear()
|
||||||
|
val list: MutableList<PumpHistoryEntry> = ArrayList()
|
||||||
|
list.addAll(medtronicHistoryData.allHistory)
|
||||||
|
|
||||||
|
//LOG.debug("Items on full list: {}", list.size());
|
||||||
|
if (group === PumpHistoryEntryGroup.All) {
|
||||||
|
filteredHistoryList.addAll(list)
|
||||||
|
} else {
|
||||||
|
for (pumpHistoryEntry in list) {
|
||||||
|
if (pumpHistoryEntry.entryType!!.group === group) {
|
||||||
|
filteredHistoryList.add(pumpHistoryEntry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
recyclerViewAdapter.setHistoryListInternal(filteredHistoryList)
|
||||||
|
recyclerViewAdapter.notifyDataSetChanged()
|
||||||
|
|
||||||
|
//LOG.debug("Items on filtered list: {}", filteredHistoryList.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
filterHistory(selectedGroup)
|
||||||
|
setHistoryTypeSpinner()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setHistoryTypeSpinner() {
|
||||||
|
manualChange = true
|
||||||
|
for (i in typeListFull!!.indices) {
|
||||||
|
if (typeListFull!![i].entryGroup === selectedGroup) {
|
||||||
|
historyTypeSpinner.setSelection(i)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SystemClock.sleep(200)
|
||||||
|
manualChange = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
//setContentView(R.layout.medtronic_history_activity)
|
||||||
|
|
||||||
|
_binding = MedtronicHistoryActivityBinding.inflate(getLayoutInflater()) //(inflater, container, false)
|
||||||
|
|
||||||
|
historyTypeSpinner = binding.medtronicHistorytype //findViewById(R.id.medtronic_historytype)
|
||||||
|
statusView = binding.medtronicHistorystatus //findViewById(R.id.medtronic_historystatus)
|
||||||
|
recyclerView = binding.medtronicHistoryRecyclerview //findViewById(R.id.medtronic_history_recyclerview)
|
||||||
|
recyclerView.setHasFixedSize(true)
|
||||||
|
llm = LinearLayoutManager(this)
|
||||||
|
recyclerView.setLayoutManager(llm)
|
||||||
|
recyclerViewAdapter = RecyclerViewAdapter(filteredHistoryList)
|
||||||
|
recyclerView.setAdapter(recyclerViewAdapter)
|
||||||
|
statusView.setVisibility(View.GONE)
|
||||||
|
typeListFull = getTypeList(getTranslatedList(resourceHelper!!))
|
||||||
|
val spinnerAdapter = ArrayAdapter(this, R.layout.spinner_centered, typeListFull)
|
||||||
|
historyTypeSpinner.setAdapter(spinnerAdapter)
|
||||||
|
historyTypeSpinner.setOnItemSelectedListener(object : AdapterView.OnItemSelectedListener {
|
||||||
|
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||||
|
if (manualChange) return
|
||||||
|
val selected = historyTypeSpinner.getSelectedItem() as TypeList
|
||||||
|
showingType = selected
|
||||||
|
selectedGroup = selected.entryGroup
|
||||||
|
filterHistory(selectedGroup)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||||
|
if (manualChange) return
|
||||||
|
filterHistory(PumpHistoryEntryGroup.All)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getTypeList(list: List<PumpHistoryEntryGroup>?): List<TypeList> {
|
||||||
|
val typeList = ArrayList<TypeList>()
|
||||||
|
for (pumpHistoryEntryGroup in list!!) {
|
||||||
|
typeList.add(TypeList(pumpHistoryEntryGroup))
|
||||||
|
}
|
||||||
|
return typeList
|
||||||
|
}
|
||||||
|
|
||||||
|
class TypeList internal constructor(var entryGroup: PumpHistoryEntryGroup) {
|
||||||
|
var name: String
|
||||||
|
override fun toString(): String {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
name = entryGroup.translated!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RecyclerViewAdapter internal constructor(var historyList: List<PumpHistoryEntry>) : RecyclerView.Adapter<RecyclerViewAdapter.HistoryViewHolder>() {
|
||||||
|
|
||||||
|
|
||||||
|
fun setHistoryListInternal(historyList: List<PumpHistoryEntry>) {
|
||||||
|
// this.historyList.clear();
|
||||||
|
// this.historyList.addAll(historyList);
|
||||||
|
this.historyList = historyList
|
||||||
|
|
||||||
|
// this.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): HistoryViewHolder {
|
||||||
|
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.medtronic_history_item, //
|
||||||
|
viewGroup, false)
|
||||||
|
return HistoryViewHolder(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: HistoryViewHolder, position: Int) {
|
||||||
|
val record = historyList[position]
|
||||||
|
if (record != null) {
|
||||||
|
holder.timeView.text = record.dateTimeString
|
||||||
|
holder.typeView.text = record.entryType!!.description
|
||||||
|
holder.valueView.text = record.displayableValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return historyList.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
|
||||||
|
super.onAttachedToRecyclerView(recyclerView)
|
||||||
|
}
|
||||||
|
|
||||||
|
class HistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
var timeView: TextView
|
||||||
|
var typeView: TextView
|
||||||
|
var valueView: TextView
|
||||||
|
|
||||||
|
init {
|
||||||
|
// cv = (CardView)itemView.findViewById(R.id.rileylink_history_item);
|
||||||
|
timeView = itemView.findViewById(R.id.medtronic_history_time)
|
||||||
|
typeView = itemView.findViewById(R.id.medtronic_history_source)
|
||||||
|
valueView = itemView.findViewById(R.id.medtronic_history_description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
var showingType: TypeList? = null
|
||||||
|
var selectedGroup = PumpHistoryEntryGroup.All
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,166 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.medtronic.dialog;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.BaseAdapter;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.android.support.DaggerFragment;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.dialog.RefreshableInterface;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.R;
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by andy on 5/19/18.
|
|
||||||
* <p>
|
|
||||||
* This is for 3rd tab, called Medtronic (in RileyLink stats), that should work similarly as the one in Loop.
|
|
||||||
* <p>
|
|
||||||
* Showing currently selected RL, speed of RL, ability to issue simple commands (getModel, tuneUp, gerProfile)
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO needs to be implemented
|
|
||||||
public class RileyLinkStatusDeviceMedtronic extends DaggerFragment implements RefreshableInterface {
|
|
||||||
|
|
||||||
@Inject ResourceHelper resourceHelper;
|
|
||||||
@Inject DateUtil dateUtil;
|
|
||||||
|
|
||||||
// @BindView(R.id.rileylink_history_list)
|
|
||||||
ListView listView;
|
|
||||||
|
|
||||||
RileyLinkCommandListAdapter adapter;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
|
||||||
View rootView = inflater.inflate(R.layout.rileylink_status_device, container, false);
|
|
||||||
|
|
||||||
adapter = new RileyLinkCommandListAdapter();
|
|
||||||
|
|
||||||
return rootView;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
this.listView = getActivity().findViewById(R.id.rileylink_history_list);
|
|
||||||
|
|
||||||
listView.setAdapter(adapter);
|
|
||||||
|
|
||||||
refreshData();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshData() {
|
|
||||||
// adapter.addItemsAndClean(RileyLinkUtil.getRileyLinkHistory());
|
|
||||||
}
|
|
||||||
|
|
||||||
static class ViewHolder {
|
|
||||||
|
|
||||||
TextView itemTime;
|
|
||||||
TextView itemSource;
|
|
||||||
TextView itemDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RileyLinkCommandListAdapter extends BaseAdapter {
|
|
||||||
|
|
||||||
private final List<RLHistoryItem> historyItemList;
|
|
||||||
private final LayoutInflater mInflator;
|
|
||||||
|
|
||||||
|
|
||||||
public RileyLinkCommandListAdapter() {
|
|
||||||
super();
|
|
||||||
historyItemList = new ArrayList<>();
|
|
||||||
mInflator = RileyLinkStatusDeviceMedtronic.this.getLayoutInflater();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void addItem(RLHistoryItem item) {
|
|
||||||
if (!historyItemList.contains(item)) {
|
|
||||||
historyItemList.add(item);
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public RLHistoryItem getHistoryItem(int position) {
|
|
||||||
return historyItemList.get(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void addItemsAndClean(List<RLHistoryItem> items) {
|
|
||||||
this.historyItemList.clear();
|
|
||||||
|
|
||||||
for (RLHistoryItem item : items) {
|
|
||||||
|
|
||||||
if (!historyItemList.contains(item)) {
|
|
||||||
historyItemList.add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
historyItemList.clear();
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return historyItemList.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getItem(int i) {
|
|
||||||
return historyItemList.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int i) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int i, View view, ViewGroup viewGroup) {
|
|
||||||
RileyLinkStatusDeviceMedtronic.ViewHolder viewHolder;
|
|
||||||
// General ListView optimization code.
|
|
||||||
if (view == null) {
|
|
||||||
view = mInflator.inflate(R.layout.rileylink_status_device_item, null);
|
|
||||||
viewHolder = new RileyLinkStatusDeviceMedtronic.ViewHolder();
|
|
||||||
viewHolder.itemTime = view.findViewById(R.id.rileylink_history_time);
|
|
||||||
viewHolder.itemSource = view.findViewById(R.id.rileylink_history_source);
|
|
||||||
viewHolder.itemDescription = view.findViewById(R.id.rileylink_history_description);
|
|
||||||
view.setTag(viewHolder);
|
|
||||||
} else {
|
|
||||||
viewHolder = (RileyLinkStatusDeviceMedtronic.ViewHolder) view.getTag();
|
|
||||||
}
|
|
||||||
|
|
||||||
RLHistoryItem item = historyItemList.get(i);
|
|
||||||
viewHolder.itemTime.setText(StringUtil.toDateTimeString(dateUtil, item.getDateTime()));
|
|
||||||
viewHolder.itemSource.setText("Riley Link"); // for now
|
|
||||||
viewHolder.itemDescription.setText(item.getDescription(resourceHelper));
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.medtronic.dialog
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.BaseAdapter
|
||||||
|
import android.widget.ListView
|
||||||
|
import android.widget.TextView
|
||||||
|
import dagger.android.support.DaggerFragment
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.dialog.RefreshableInterface
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil
|
||||||
|
import info.nightscout.androidaps.plugins.pump.medtronic.R
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by andy on 5/19/18.
|
||||||
|
* NOTE: This class is not used yet, so it has no Bindings
|
||||||
|
*
|
||||||
|
* This is for 3rd tab, called Medtronic (in RileyLink stats), that should work similarly as the one in Loop.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Showing currently selected RL, speed of RL, ability to issue simple commands (getModel, tuneUp, gerProfile)
|
||||||
|
*/
|
||||||
|
// TODO needs to be implemented
|
||||||
|
class RileyLinkStatusDeviceMedtronic : DaggerFragment(), RefreshableInterface {
|
||||||
|
|
||||||
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
|
|
||||||
|
var listView: ListView? = null
|
||||||
|
var adapter: RileyLinkCommandListAdapter? = null
|
||||||
|
|
||||||
|
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||||
|
//private var _binding: RileyLinkStatusDeviceBinding? = null
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
|
||||||
|
// _binding = LoopFragmentBinding.inflate(inflater, container, false)
|
||||||
|
// return binding.root
|
||||||
|
|
||||||
|
|
||||||
|
val rootView = inflater.inflate(R.layout.rileylink_status_device, container, false)
|
||||||
|
adapter = RileyLinkCommandListAdapter()
|
||||||
|
return rootView
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
//listView = activity!!.findViewById(R.id.rileylink_history_list)
|
||||||
|
//listView.setAdapter(adapter)
|
||||||
|
refreshData()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun refreshData() {
|
||||||
|
// adapter.addItemsAndClean(RileyLinkUtil.getRileyLinkHistory());
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ViewHolder {
|
||||||
|
var itemTime: TextView? = null
|
||||||
|
var itemSource: TextView? = null
|
||||||
|
var itemDescription: TextView? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class RileyLinkCommandListAdapter : BaseAdapter() {
|
||||||
|
private val historyItemList: MutableList<RLHistoryItem>
|
||||||
|
private val mInflator: LayoutInflater
|
||||||
|
fun addItem(item: RLHistoryItem) {
|
||||||
|
if (!historyItemList.contains(item)) {
|
||||||
|
historyItemList.add(item)
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getHistoryItem(position: Int): RLHistoryItem {
|
||||||
|
return historyItemList[position]
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addItemsAndClean(items: List<RLHistoryItem>) {
|
||||||
|
historyItemList.clear()
|
||||||
|
for (item in items) {
|
||||||
|
if (!historyItemList.contains(item)) {
|
||||||
|
historyItemList.add(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
historyItemList.clear()
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCount(): Int {
|
||||||
|
return historyItemList.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItem(i: Int): Any {
|
||||||
|
return historyItemList[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemId(i: Int): Long {
|
||||||
|
return i.toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getView(i: Int, view: View, viewGroup: ViewGroup): View {
|
||||||
|
var view = view
|
||||||
|
val viewHolder: ViewHolder
|
||||||
|
// General ListView optimization code.
|
||||||
|
if (view == null) {
|
||||||
|
view = mInflator.inflate(R.layout.rileylink_status_device_item, null)
|
||||||
|
viewHolder = ViewHolder()
|
||||||
|
viewHolder.itemTime = view.findViewById(R.id.rileylink_history_time)
|
||||||
|
viewHolder.itemSource = view.findViewById(R.id.rileylink_history_source)
|
||||||
|
viewHolder.itemDescription = view.findViewById(R.id.rileylink_history_description)
|
||||||
|
view.tag = viewHolder
|
||||||
|
} else {
|
||||||
|
viewHolder = view.tag as ViewHolder
|
||||||
|
}
|
||||||
|
val item = historyItemList[i]
|
||||||
|
viewHolder.itemTime!!.text = StringUtil.toDateTimeString(dateUtil, item.dateTime)
|
||||||
|
viewHolder.itemSource!!.text = "Riley Link" // for now
|
||||||
|
viewHolder.itemDescription!!.text = item.getDescription(resourceHelper)
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
historyItemList = ArrayList()
|
||||||
|
mInflator = this@RileyLinkStatusDeviceMedtronic.layoutInflater
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,6 +49,7 @@ class RileyLinkMedtronicService // This empty constructor must be kept, otherwi
|
||||||
private var encodingType: RileyLinkEncodingType? = null
|
private var encodingType: RileyLinkEncodingType? = null
|
||||||
private var encodingChanged = false
|
private var encodingChanged = false
|
||||||
private var inPreInit = true
|
private var inPreInit = true
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly created")
|
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly created")
|
||||||
|
@ -267,19 +268,19 @@ class RileyLinkMedtronicService // This empty constructor must be kept, otherwi
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkParameterValue(key: Int, defaultValue: String, defaultValueDouble: Double): Double {
|
private fun checkParameterValue(key: Int, defaultValue: String, defaultValueDouble: Double): Double {
|
||||||
var `val`: Double
|
var valueDouble: Double
|
||||||
val value = sp.getString(key, defaultValue)
|
val value = sp.getString(key, defaultValue)
|
||||||
`val` = try {
|
valueDouble = try {
|
||||||
value.toDouble()
|
value.toDouble()
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
aapsLogger.error("Error parsing setting: %s, value found %s", key, value)
|
aapsLogger.error("Error parsing setting: %s, value found %s", key, value)
|
||||||
defaultValueDouble
|
defaultValueDouble
|
||||||
}
|
}
|
||||||
if (`val` > defaultValueDouble) {
|
if (valueDouble > defaultValueDouble) {
|
||||||
sp.putString(key, defaultValue)
|
sp.putString(key, defaultValue)
|
||||||
`val` = defaultValueDouble
|
valueDouble = defaultValueDouble
|
||||||
}
|
}
|
||||||
return `val`
|
return valueDouble
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setNotInPreInit(): Boolean {
|
fun setNotInPreInit(): Boolean {
|
||||||
|
|
|
@ -33,6 +33,7 @@ enum class PumpHistoryEntryGroup(val resourceId: Int) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private var translatedList: MutableList<PumpHistoryEntryGroup>? = null
|
private var translatedList: MutableList<PumpHistoryEntryGroup>? = null
|
||||||
|
|
||||||
private fun doTranslation(resourceHelper: ResourceHelper) {
|
private fun doTranslation(resourceHelper: ResourceHelper) {
|
||||||
translatedList = ArrayList()
|
translatedList = ArrayList()
|
||||||
for (pumpHistoryEntryGroup in values()) {
|
for (pumpHistoryEntryGroup in values()) {
|
||||||
|
@ -41,7 +42,8 @@ enum class PumpHistoryEntryGroup(val resourceId: Int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic fun getTranslatedList(resourceHelper: ResourceHelper): List<PumpHistoryEntryGroup>? {
|
@JvmStatic
|
||||||
|
fun getTranslatedList(resourceHelper: ResourceHelper): List<PumpHistoryEntryGroup>? {
|
||||||
if (translatedList == null) doTranslation(resourceHelper)
|
if (translatedList == null) doTranslation(resourceHelper)
|
||||||
return translatedList
|
return translatedList
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusDevice">
|
tools:context=".plugins.pump.medtronic.dialog.RileyLinkStatusDevice">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
Loading…
Reference in a new issue