- kotlin changes to most of the classes, most of it is tested
This commit is contained in:
parent
bb657a2498
commit
a202178426
76 changed files with 2581 additions and 4173 deletions
|
@ -1,5 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.general.actions.defs
|
||||
|
||||
interface CustomActionType {
|
||||
val key: String?
|
||||
fun getKey(): String
|
||||
}
|
|
@ -244,7 +244,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
|||
|
||||
public long lastDataTime() {
|
||||
aapsLogger.debug(LTag.PUMP, "lastDataTime [PumpPluginAbstract].");
|
||||
return getPumpStatusData().lastConnection;
|
||||
return getPumpStatusData().getLastConnection();
|
||||
}
|
||||
|
||||
|
||||
|
@ -308,7 +308,8 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
|||
|
||||
// Pump capabilities
|
||||
|
||||
@NonNull public PumpDescription getPumpDescription() {
|
||||
|
||||
public PumpDescription getPumpDescription() {
|
||||
return pumpDescription;
|
||||
}
|
||||
|
||||
|
@ -331,7 +332,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
|||
@NonNull @Override
|
||||
public JSONObject getJSONStatus(@NonNull Profile profile, @NonNull String profileName, @NonNull String version) {
|
||||
|
||||
if ((getPumpStatusData().lastConnection + 60 * 60 * 1000L) < System.currentTimeMillis()) {
|
||||
if ((getPumpStatusData().getLastConnection() + 60 * 60 * 1000L) < System.currentTimeMillis()) {
|
||||
return new JSONObject();
|
||||
}
|
||||
|
||||
|
@ -341,8 +342,8 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
|||
JSONObject status = new JSONObject();
|
||||
JSONObject extended = new JSONObject();
|
||||
try {
|
||||
battery.put("percent", getPumpStatusData().batteryRemaining);
|
||||
status.put("status", getPumpStatusData().pumpStatusType != null ? getPumpStatusData().pumpStatusType.getStatus() : "normal");
|
||||
battery.put("percent", getPumpStatusData().getBatteryRemaining());
|
||||
status.put("status", getPumpStatusData().getPumpStatusType() != null ? getPumpStatusData().getPumpStatusType().getStatus() : "normal");
|
||||
extended.put("Version", version);
|
||||
try {
|
||||
extended.put("ActiveProfile", profileName);
|
||||
|
@ -368,7 +369,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
|||
pump.put("battery", battery);
|
||||
pump.put("status", status);
|
||||
pump.put("extended", extended);
|
||||
pump.put("reservoir", getPumpStatusData().reservoirRemainingUnits);
|
||||
pump.put("reservoir", getPumpStatusData().getReservoirRemainingUnits());
|
||||
pump.put("clock", dateUtil.toISOString(dateUtil.now()));
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
|
@ -381,14 +382,14 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
|||
@NonNull @Override
|
||||
public String shortStatus(boolean veryShort) {
|
||||
String ret = "";
|
||||
if (getPumpStatusData().lastConnection != 0) {
|
||||
long agoMsec = System.currentTimeMillis() - getPumpStatusData().lastConnection;
|
||||
if (getPumpStatusData().getLastConnection() != 0) {
|
||||
long agoMsec = System.currentTimeMillis() - getPumpStatusData().getLastConnection();
|
||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
||||
ret += "LastConn: " + agoMin + " min ago\n";
|
||||
}
|
||||
if (getPumpStatusData().lastBolusTime != null && getPumpStatusData().lastBolusTime.getTime() != 0) {
|
||||
ret += "LastBolus: " + DecimalFormatter.INSTANCE.to2Decimal(getPumpStatusData().lastBolusAmount) + "U @" + //
|
||||
android.text.format.DateFormat.format("HH:mm", getPumpStatusData().lastBolusTime) + "\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) {
|
||||
|
@ -402,9 +403,9 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
|||
// ret += "TDD: " + DecimalFormatter.to0Decimal(pumpStatus.dailyTotalUnits) + " / "
|
||||
// + pumpStatus.maxDailyTotalUnits + " U\n";
|
||||
// }
|
||||
ret += "IOB: " + getPumpStatusData().iob + "U\n";
|
||||
ret += "Reserv: " + DecimalFormatter.INSTANCE.to0Decimal(getPumpStatusData().reservoirRemainingUnits) + "U\n";
|
||||
ret += "Batt: " + getPumpStatusData().batteryRemaining + "\n";
|
||||
ret += "IOB: " + getPumpStatusData().getIob() + "U\n";
|
||||
ret += "Reserv: " + DecimalFormatter.INSTANCE.to0Decimal(getPumpStatusData().getReservoirRemainingUnits()) + "U\n";
|
||||
ret += "Batt: " + getPumpStatusData().getBatteryRemaining() + "\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,535 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.common;
|
||||
|
||||
import static info.nightscout.androidaps.extensions.PumpStateExtensionKt.convertedToAbsolute;
|
||||
import static info.nightscout.androidaps.extensions.PumpStateExtensionKt.getPlannedRemainingMinutes;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
<<<<<<< HEAD
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
=======
|
||||
>>>>>>> meallink
|
||||
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.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventCustomActionsChanged;
|
||||
import info.nightscout.androidaps.extensions.PumpStateExtensionKt;
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider;
|
||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* 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 PumpInterface, ConstraintsInterface {
|
||||
private final CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
protected HasAndroidInjector injector;
|
||||
protected AAPSLogger aapsLogger;
|
||||
protected RxBusWrapper rxBus;
|
||||
protected ActivePluginProvider 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;
|
||||
<<<<<<< HEAD
|
||||
|
||||
=======
|
||||
>>>>>>> meallink
|
||||
|
||||
protected PumpPluginAbstract(
|
||||
PluginDescription pluginDescription,
|
||||
PumpType pumpType,
|
||||
HasAndroidInjector injector,
|
||||
ResourceHelper resourceHelper,
|
||||
AAPSLogger aapsLogger,
|
||||
CommandQueueProvider commandQueue,
|
||||
RxBusWrapper rxBus,
|
||||
ActivePluginProvider 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().lastConnection;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
@NonNull 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().lastConnection + 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().batteryRemaining);
|
||||
status.put("status", getPumpStatusData().pumpStatusType != null ? getPumpStatusData().pumpStatusType.getStatus() : "normal");
|
||||
extended.put("Version", version);
|
||||
try {
|
||||
extended.put("ActiveProfile", profileName);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
// TODO fix
|
||||
TemporaryBasal tb = activePlugin.getActiveTreatments().getTempBasalFromHistory(System.currentTimeMillis());
|
||||
=======
|
||||
PumpSync.PumpState.TemporaryBasal tb = pumpSync.expectedPumpState().getTemporaryBasal();
|
||||
>>>>>>> meallink
|
||||
if (tb != null) {
|
||||
extended.put("TempBasalAbsoluteRate", convertedToAbsolute(tb, now, profile));
|
||||
extended.put("TempBasalStart", dateUtil.dateAndTimeString(tb.getTimestamp()));
|
||||
extended.put("TempBasalRemaining", getPlannedRemainingMinutes(tb));
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
// TODO fix
|
||||
ExtendedBolus eb = activePlugin.getActiveTreatments().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
=======
|
||||
PumpSync.PumpState.ExtendedBolus eb = pumpSync.expectedPumpState().getExtendedBolus();
|
||||
>>>>>>> meallink
|
||||
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().reservoirRemainingUnits);
|
||||
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().lastConnection != 0) {
|
||||
long agoMsec = System.currentTimeMillis() - getPumpStatusData().lastConnection;
|
||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
||||
ret += "LastConn: " + agoMin + " min ago\n";
|
||||
}
|
||||
if (getPumpStatusData().lastBolusTime != null && getPumpStatusData().lastBolusTime.getTime() != 0) {
|
||||
ret += "LastBolus: " + DecimalFormatter.INSTANCE.to2Decimal(getPumpStatusData().lastBolusAmount) + "U @" + //
|
||||
android.text.format.DateFormat.format("HH:mm", getPumpStatusData().lastBolusTime) + "\n";
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
// TODO fix
|
||||
TemporaryBasal activeTemp = activePlugin.getActiveTreatments().getRealTempBasalFromHistory(System.currentTimeMillis());
|
||||
=======
|
||||
PumpSync.PumpState.TemporaryBasal activeTemp = pumpSync.expectedPumpState().getTemporaryBasal();
|
||||
>>>>>>> meallink
|
||||
if (activeTemp != null) {
|
||||
ret += "Temp: " + PumpStateExtensionKt.toStringFull(activeTemp, dateUtil) + "\n";
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
// TODO fix
|
||||
ExtendedBolus activeExtendedBolus = activePlugin.getActiveTreatments().getExtendedBolusFromHistory(
|
||||
System.currentTimeMillis());
|
||||
=======
|
||||
PumpSync.PumpState.ExtendedBolus activeExtendedBolus = pumpSync.expectedPumpState().getExtendedBolus();
|
||||
>>>>>>> meallink
|
||||
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().iob + "U\n";
|
||||
ret += "Reserv: " + DecimalFormatter.INSTANCE.to0Decimal(getPumpStatusData().reservoirRemainingUnits) + "U\n";
|
||||
ret += "Batt: " + getPumpStatusData().batteryRemaining + "\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);
|
||||
|
||||
public boolean addBolusWithTempId(DetailedBolusInfo detailedBolusInfo, boolean writeToInternalHistory) {
|
||||
long temporaryId = generateTempId(detailedBolusInfo.timestamp);
|
||||
boolean response = pumpSync.addBolusWithTempId(detailedBolusInfo.timestamp, detailedBolusInfo.insulin,
|
||||
generateTempId(detailedBolusInfo.timestamp), detailedBolusInfo.getBolusType(),
|
||||
getPumpType(), serialNumber());
|
||||
|
||||
if (response && writeToInternalHistory) {
|
||||
driverHistory.put(temporaryId, new PumpDbEntry(temporaryId, model(), serialNumber(), detailedBolusInfo));
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public void removeTemporaryId(long temporaryId) {
|
||||
driverHistory.remove(temporaryId);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.common.data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import info.nightscout.androidaps.interfaces.ProfileStore;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpStatusType;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 4/28/18.
|
||||
*/
|
||||
|
||||
public abstract class PumpStatus {
|
||||
|
||||
// connection
|
||||
public long lastDataTime;
|
||||
public long lastConnection = 0L;
|
||||
public long previousConnection = 0L; // here should be stored last connection of previous session (so needs to be
|
||||
// read before lastConnection is modified for first time).
|
||||
|
||||
// last bolus
|
||||
public Date lastBolusTime;
|
||||
public Double lastBolusAmount;
|
||||
|
||||
// other pump settings
|
||||
public String activeProfileName = "0";
|
||||
public double reservoirRemainingUnits = 0.0d;
|
||||
public int reservoirFullUnits = 0;
|
||||
public int batteryRemaining = 0; // percent, so 0-100
|
||||
public Double batteryVoltage = null;
|
||||
|
||||
|
||||
// iob
|
||||
public String iob = null;
|
||||
|
||||
// TDD
|
||||
public Double dailyTotalUnits;
|
||||
public String maxDailyTotalUnits;
|
||||
public boolean validBasalRateProfileSelectedOnPump = true;
|
||||
public ProfileStore profileStore;
|
||||
public String units; // Constants.MGDL or Constants.MMOL
|
||||
public PumpStatusType pumpStatusType = PumpStatusType.Running;
|
||||
public Double[] basalsByHour;
|
||||
public double currentBasal = 0;
|
||||
public int tempBasalInProgress = 0;
|
||||
public int tempBasalRatio = 0;
|
||||
public int tempBasalRemainMin = 0;
|
||||
public Date tempBasalStart;
|
||||
public PumpType pumpType;
|
||||
//protected PumpDescription pumpDescription;
|
||||
|
||||
|
||||
public PumpStatus(PumpType pumpType) {
|
||||
// public PumpStatus(PumpDescription pumpDescription) {
|
||||
// this.pumpDescription = pumpDescription;
|
||||
|
||||
// this.initSettings();
|
||||
this.pumpType = pumpType;
|
||||
}
|
||||
|
||||
public abstract void initSettings();
|
||||
|
||||
public void setLastCommunicationToNow() {
|
||||
this.lastDataTime = System.currentTimeMillis();
|
||||
this.lastConnection = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public abstract String getErrorInfo();
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package info.nightscout.androidaps.plugins.pump.common.data
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpStatusType
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by andy on 4/28/18.
|
||||
*/
|
||||
abstract class PumpStatus(var pumpType: PumpType) {
|
||||
|
||||
// connection
|
||||
var lastDataTime: Long = 0
|
||||
var lastConnection = 0L
|
||||
var previousConnection = 0L // here should be stored last connection of previous session (so needs to be
|
||||
|
||||
// read before lastConnection is modified for first time).
|
||||
// last bolus
|
||||
var lastBolusTime: Date? = null
|
||||
var lastBolusAmount: Double? = null
|
||||
|
||||
// other pump settings
|
||||
var activeProfileName = "0"
|
||||
var reservoirRemainingUnits = 0.0
|
||||
var reservoirFullUnits = 0
|
||||
var batteryRemaining = 0 // percent, so 0-100
|
||||
var batteryVoltage: Double? = null
|
||||
|
||||
// iob
|
||||
var iob: String? = null
|
||||
|
||||
// TDD
|
||||
var dailyTotalUnits: Double? = null
|
||||
var maxDailyTotalUnits: String? = null
|
||||
var units : String? = null // Constants.MGDL or Constants.MMOL
|
||||
var pumpStatusType = PumpStatusType.Running
|
||||
var basalsByHour: Array<Double>? = null
|
||||
var tempBasalStart: Date? = null
|
||||
var tempBasalAmount: Double? = 0.0
|
||||
var tempBasalLength: Int? = 0
|
||||
var tempBasalEnd: Long? = null
|
||||
|
||||
abstract fun initSettings()
|
||||
|
||||
fun setLastCommunicationToNow() {
|
||||
lastDataTime = System.currentTimeMillis()
|
||||
lastConnection = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
abstract val errorInfo: String?
|
||||
|
||||
}
|
|
@ -220,12 +220,12 @@ class MedtronicFragment : DaggerFragment() {
|
|||
PumpDeviceState.InvalidConfiguration -> binding.pumpStatusIcon.text = " " + resourceHelper.gs(medtronicPumpStatus.pumpDeviceState.resourceId)
|
||||
|
||||
PumpDeviceState.Active -> {
|
||||
val cmd = medtronicUtil.currentCommand
|
||||
val cmd = medtronicUtil.getCurrentCommand()
|
||||
if (cmd == null)
|
||||
binding.pumpStatusIcon.text = " " + resourceHelper.gs(medtronicPumpStatus.pumpDeviceState.resourceId)
|
||||
else {
|
||||
aapsLogger.debug(LTag.PUMP, "Command: $cmd")
|
||||
val cmdResourceId = cmd.resourceId
|
||||
val cmdResourceId = cmd.resourceId!!
|
||||
if (cmd == MedtronicCommandType.GetHistoryData) {
|
||||
binding.pumpStatusIcon.text = medtronicUtil.frameNumber?.let {
|
||||
resourceHelper.gs(cmdResourceId, medtronicUtil.pageNumber, medtronicUtil.frameNumber)
|
||||
|
@ -233,7 +233,7 @@ class MedtronicFragment : DaggerFragment() {
|
|||
?: resourceHelper.gs(R.string.medtronic_cmd_desc_get_history_request, medtronicUtil.pageNumber)
|
||||
} else {
|
||||
binding.pumpStatusIcon.text = " " + (cmdResourceId?.let { resourceHelper.gs(it) }
|
||||
?: cmd.getCommandDescription())
|
||||
?: cmd.commandDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -298,34 +298,31 @@ class MedtronicFragment : DaggerFragment() {
|
|||
val bolus = medtronicPumpStatus.lastBolusAmount
|
||||
val bolusTime = medtronicPumpStatus.lastBolusTime
|
||||
if (bolus != null && bolusTime != null) {
|
||||
val agoMsc = System.currentTimeMillis() - medtronicPumpStatus.lastBolusTime.time
|
||||
val agoMsc = System.currentTimeMillis() - medtronicPumpStatus.lastBolusTime!!.time
|
||||
val bolusMinAgo = agoMsc.toDouble() / 60.0 / 1000.0
|
||||
val unit = resourceHelper.gs(R.string.insulin_unit_shortname)
|
||||
val ago = when {
|
||||
agoMsc < 60 * 1000 -> resourceHelper.gs(R.string.medtronic_pump_connected_now)
|
||||
bolusMinAgo < 60 -> dateUtil.minAgo(resourceHelper, medtronicPumpStatus.lastBolusTime.time)
|
||||
else -> dateUtil.hourAgo(medtronicPumpStatus.lastBolusTime.time, resourceHelper)
|
||||
bolusMinAgo < 60 -> dateUtil.minAgo(resourceHelper, medtronicPumpStatus.lastBolusTime!!.time)
|
||||
else -> dateUtil.hourAgo(medtronicPumpStatus.lastBolusTime!!.time, resourceHelper)
|
||||
}
|
||||
binding.lastBolus.text = resourceHelper.gs(R.string.mdt_last_bolus, bolus, unit, ago)
|
||||
} else {
|
||||
binding.lastBolus.text = ""
|
||||
}
|
||||
|
||||
if (true) {
|
||||
// base basal rate
|
||||
binding.baseBasalRate.text = ("(" + medtronicPumpStatus.activeProfileName + ") "
|
||||
+ resourceHelper.gs(R.string.pump_basebasalrate, medtronicPumpPlugin.baseBasalRate))
|
||||
|
||||
binding.tempBasal.text = "??"
|
||||
} else {
|
||||
val pumpState = pumpSync.expectedPumpState()
|
||||
// base basal rate
|
||||
binding.baseBasalRate.text = ("(" + medtronicPumpStatus.activeProfileName + ") "
|
||||
+ resourceHelper.gs(R.string.pump_basebasalrate, medtronicPumpPlugin.baseBasalRate))
|
||||
// TBR
|
||||
var tbrStr = ""
|
||||
var tbrRemainingTime: Int? = medtronicPumpStatus.tbrRemainingTime
|
||||
|
||||
binding.tempBasal.text = pumpState.temporaryBasal?.toStringFull(dateUtil)
|
||||
?: ""
|
||||
if (tbrRemainingTime!=null) {
|
||||
tbrStr = resourceHelper.gs(R.string.mdt_tbr_remaining, medtronicPumpStatus.tempBasalAmount, tbrRemainingTime);
|
||||
}
|
||||
binding.tempBasal.text = tbrStr
|
||||
|
||||
// battery
|
||||
if (medtronicPumpStatus.batteryType == BatteryType.None || medtronicPumpStatus.batteryVoltage == null) {
|
||||
|
|
|
@ -40,6 +40,7 @@ import info.nightscout.androidaps.interfaces.CommandQueueProvider;
|
|||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.interfaces.Pump;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpSync;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
|
@ -210,19 +211,24 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
return "MedtronicPumpPlugin::";
|
||||
}
|
||||
|
||||
// public PumpDescription getPumpDescription() {
|
||||
// return super.pumpDescription;
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
public void initPumpStatusData() {
|
||||
|
||||
medtronicPumpStatus.lastConnection = sp.getLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
|
||||
medtronicPumpStatus.lastDataTime = medtronicPumpStatus.lastConnection;
|
||||
medtronicPumpStatus.previousConnection = medtronicPumpStatus.lastConnection;
|
||||
medtronicPumpStatus.setLastConnection(sp.getLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L));
|
||||
medtronicPumpStatus.setLastDataTime(medtronicPumpStatus.getLastConnection());
|
||||
medtronicPumpStatus.setPreviousConnection( medtronicPumpStatus.getLastConnection());
|
||||
|
||||
//if (rileyLinkMedtronicService != null) rileyLinkMedtronicService.verifyConfiguration();
|
||||
|
||||
aapsLogger.debug(LTag.PUMP, "initPumpStatusData: " + this.medtronicPumpStatus);
|
||||
|
||||
// this is only thing that can change, by being configured
|
||||
pumpDescription.setMaxTempAbsolute((medtronicPumpStatus.maxBasal != null) ? medtronicPumpStatus.maxBasal : 35.0d);
|
||||
pumpDescription.setMaxTempAbsolute((medtronicPumpStatus.getMaxBasal() != null) ? medtronicPumpStatus.getMaxBasal() : 35.0d);
|
||||
|
||||
// set first Medtronic Pump Start
|
||||
if (!sp.contains(MedtronicConst.Statistics.FirstPumpStart)) {
|
||||
|
@ -321,15 +327,16 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
return rileyLinkMedtronicService;
|
||||
}
|
||||
|
||||
@Override public RileyLinkPumpInfo getPumpInfo() {
|
||||
String frequency = resourceHelper.gs(medtronicPumpStatus.pumpFrequency.equals("medtronic_pump_frequency_us_ca") ? R.string.medtronic_pump_frequency_us_ca : R.string.medtronic_pump_frequency_worldwide);
|
||||
String model = medtronicPumpStatus.medtronicDeviceType == null ? "???" : "Medtronic " + medtronicPumpStatus.medtronicDeviceType.getPumpModel();
|
||||
String serialNumber = medtronicPumpStatus.serialNumber;
|
||||
@Override
|
||||
public RileyLinkPumpInfo getPumpInfo() {
|
||||
String frequency = resourceHelper.gs(medtronicPumpStatus.getPumpFrequency().equals("medtronic_pump_frequency_us_ca") ? R.string.medtronic_pump_frequency_us_ca : R.string.medtronic_pump_frequency_worldwide);
|
||||
String model = medtronicPumpStatus.getMedtronicDeviceType() == null ? "???" : "Medtronic " + medtronicPumpStatus.getMedtronicDeviceType().getPumpModel();
|
||||
String serialNumber = medtronicPumpStatus.getSerialNumber();
|
||||
return new RileyLinkPumpInfo(frequency, model, serialNumber);
|
||||
}
|
||||
|
||||
@Override public long getLastConnectionTimeMillis() {
|
||||
return medtronicPumpStatus.lastConnection;
|
||||
return medtronicPumpStatus.getLastConnection();
|
||||
}
|
||||
|
||||
@Override public void setLastCommunicationToNow() {
|
||||
|
@ -580,7 +587,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
if (medtronicUtil.getMedtronicPumpModel() == null) {
|
||||
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.PumpModel);
|
||||
} else {
|
||||
if (medtronicPumpStatus.medtronicDeviceType != medtronicUtil.getMedtronicPumpModel()) {
|
||||
if (medtronicPumpStatus.getMedtronicDeviceType() != medtronicUtil.getMedtronicPumpModel()) {
|
||||
aapsLogger.warn(LTag.PUMP, getLogPrefix() + "Configured pump is not the same as one detected.");
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpTypeNotSame, getResourceHelper(), rxBus);
|
||||
}
|
||||
|
@ -643,27 +650,27 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
|
||||
@Override
|
||||
public boolean isThisProfileSet(@NonNull Profile profile) {
|
||||
aapsLogger.debug(LTag.PUMP, "isThisProfileSet: basalInitalized=" + medtronicPumpStatus.basalProfileStatus);
|
||||
aapsLogger.debug(LTag.PUMP, "isThisProfileSet: basalInitalized=" + medtronicPumpStatus.getBasalProfileStatus());
|
||||
|
||||
if (!isInitialized)
|
||||
return true;
|
||||
|
||||
if (medtronicPumpStatus.basalProfileStatus == BasalProfileStatus.NotInitialized) {
|
||||
if (medtronicPumpStatus.getBasalProfileStatus() == BasalProfileStatus.NotInitialized) {
|
||||
// this shouldn't happen, but if there was problem we try again
|
||||
getBasalProfiles();
|
||||
return isProfileSame(profile);
|
||||
} else if (medtronicPumpStatus.basalProfileStatus == BasalProfileStatus.ProfileChanged) {
|
||||
} else if (medtronicPumpStatus.getBasalProfileStatus() == BasalProfileStatus.ProfileChanged) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (medtronicPumpStatus.basalProfileStatus != BasalProfileStatus.ProfileOK) || isProfileSame(profile);
|
||||
return (medtronicPumpStatus.getBasalProfileStatus() != BasalProfileStatus.ProfileOK) || isProfileSame(profile);
|
||||
}
|
||||
|
||||
|
||||
private boolean isProfileSame(Profile profile) {
|
||||
|
||||
boolean invalid = false;
|
||||
Double[] basalsByHour = medtronicPumpStatus.basalsByHour;
|
||||
Double[] basalsByHour = medtronicPumpStatus.getBasalsByHour();
|
||||
|
||||
aapsLogger.debug(LTag.PUMP, "Current Basals (h): "
|
||||
+ (basalsByHour == null ? "null" : BasalProfile.getProfilesByHourToString(basalsByHour)));
|
||||
|
@ -704,8 +711,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
@Override
|
||||
public long lastDataTime() {
|
||||
|
||||
if (medtronicPumpStatus.lastConnection != 0) {
|
||||
return medtronicPumpStatus.lastConnection;
|
||||
if (medtronicPumpStatus.getLastConnection() != 0) {
|
||||
return medtronicPumpStatus.getLastConnection();
|
||||
}
|
||||
|
||||
return System.currentTimeMillis();
|
||||
|
@ -720,13 +727,13 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
|
||||
@Override
|
||||
public double getReservoirLevel() {
|
||||
return medtronicPumpStatus.reservoirRemainingUnits;
|
||||
return medtronicPumpStatus.getReservoirRemainingUnits();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBatteryLevel() {
|
||||
return medtronicPumpStatus.batteryRemaining;
|
||||
return medtronicPumpStatus.getBatteryRemaining();
|
||||
}
|
||||
|
||||
protected void triggerUIChange() {
|
||||
|
@ -778,22 +785,22 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
if (clock == null)
|
||||
return;
|
||||
|
||||
int timeDiff = Math.abs(clock.timeDifference);
|
||||
int timeDiff = Math.abs(clock.getTimeDifference());
|
||||
|
||||
if (timeDiff > 20) {
|
||||
|
||||
if ((clock.localDeviceTime.getYear() <= 2015) || (timeDiff <= 24 * 60 * 60)) {
|
||||
if ((clock.getLocalDeviceTime().getYear() <= 2015) || (timeDiff <= 24 * 60 * 60)) {
|
||||
|
||||
aapsLogger.info(LTag.PUMP, String.format(Locale.ENGLISH, "MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference is %d s. Set time on pump.", timeDiff));
|
||||
|
||||
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetRealTimeClock);
|
||||
|
||||
if (clock.timeDifference == 0) {
|
||||
if (clock.getTimeDifference() == 0) {
|
||||
Notification notification = new Notification(Notification.INSIGHT_DATE_TIME_UPDATED, getResourceHelper().gs(R.string.pump_time_updated), Notification.INFO, 60);
|
||||
rxBus.send(new EventNewNotification(notification));
|
||||
}
|
||||
} else {
|
||||
if ((clock.localDeviceTime.getYear() > 2015)) {
|
||||
if ((clock.getLocalDeviceTime().getYear() > 2015)) {
|
||||
aapsLogger.error(String.format(Locale.ENGLISH, "MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference over 24h requested [diff=%d s]. Doing nothing.", timeDiff));
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.TimeChangeOver24h, getResourceHelper(), rxBus);
|
||||
}
|
||||
|
@ -814,12 +821,12 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
|
||||
setRefreshButtonEnabled(false);
|
||||
|
||||
if (detailedBolusInfo.insulin > medtronicPumpStatus.reservoirRemainingUnits) {
|
||||
if (detailedBolusInfo.insulin > medtronicPumpStatus.getReservoirRemainingUnits()) {
|
||||
return new PumpEnactResult(getInjector()) //
|
||||
.success(false) //
|
||||
.enacted(false) //
|
||||
.comment(getResourceHelper().gs(R.string.medtronic_cmd_bolus_could_not_be_delivered_no_insulin,
|
||||
medtronicPumpStatus.reservoirRemainingUnits,
|
||||
medtronicPumpStatus.getReservoirRemainingUnits(),
|
||||
detailedBolusInfo.insulin));
|
||||
}
|
||||
|
||||
|
@ -857,9 +864,9 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery");
|
||||
|
||||
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetBolus,
|
||||
detailedBolusInfo.insulin);
|
||||
Arrays.asList(detailedBolusInfo.insulin));
|
||||
|
||||
Boolean response = (Boolean) responseTask.returnData;
|
||||
Boolean response = (Boolean) responseTask.getResult();
|
||||
|
||||
setRefreshButtonEnabled(true);
|
||||
|
||||
|
@ -894,7 +901,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
}
|
||||
|
||||
// we subtract insulin, exact amount will be visible with next remainingInsulin update.
|
||||
medtronicPumpStatus.reservoirRemainingUnits -= detailedBolusInfo.insulin;
|
||||
medtronicPumpStatus.setReservoirRemainingUnits(medtronicPumpStatus.getReservoirRemainingUnits() - detailedBolusInfo.insulin);
|
||||
|
||||
incrementStatistics(detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB ? MedtronicConst.Statistics.SMBBoluses
|
||||
: MedtronicConst.Statistics.StandardBoluses);
|
||||
|
@ -1022,7 +1029,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
|
||||
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.CancelTBR);
|
||||
|
||||
Boolean response = (Boolean) responseTask2.returnData;
|
||||
Boolean response = (Boolean) responseTask2.getResult();
|
||||
|
||||
if (response) {
|
||||
aapsLogger.info(LTag.PUMP, getLogPrefix() + "setTempBasalAbsolute - Current TBR cancelled.");
|
||||
|
@ -1038,17 +1045,17 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
|
||||
// now start new TBR
|
||||
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetTemporaryBasal,
|
||||
absoluteRate, durationInMinutes);
|
||||
Arrays.asList(absoluteRate, durationInMinutes));
|
||||
|
||||
Boolean response = (Boolean) responseTask.returnData;
|
||||
Boolean response = (Boolean) responseTask.getResult();
|
||||
|
||||
aapsLogger.info(LTag.PUMP, getLogPrefix() + "setTempBasalAbsolute - setTBR. Response: " + response);
|
||||
|
||||
if (response) {
|
||||
// FIXME put this into UIPostProcessor
|
||||
medtronicPumpStatus.tempBasalStart = new Date();
|
||||
medtronicPumpStatus.tempBasalAmount = absoluteRate;
|
||||
medtronicPumpStatus.tempBasalLength = durationInMinutes;
|
||||
medtronicPumpStatus.setTempBasalStart(new Date());
|
||||
medtronicPumpStatus.setTempBasalAmount(absoluteRate);
|
||||
medtronicPumpStatus.setTempBasalLength(durationInMinutes);
|
||||
|
||||
TemporaryBasal tempStart = new TemporaryBasal(getInjector()) //
|
||||
.date(System.currentTimeMillis()) //
|
||||
|
@ -1122,7 +1129,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
scheduleNextRefresh(MedtronicStatusRefreshType.PumpTime, -1);
|
||||
}
|
||||
|
||||
if (this.medtronicPumpStatus.basalProfileStatus != BasalProfileStatus.NotInitialized
|
||||
if (this.medtronicPumpStatus.getBasalProfileStatus() != BasalProfileStatus.NotInitialized
|
||||
&& medtronicHistoryData.hasBasalProfileChanged()) {
|
||||
medtronicHistoryData.processLastBasalProfileChange(pumpDescription.getPumpType(), medtronicPumpStatus);
|
||||
}
|
||||
|
@ -1194,7 +1201,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
}
|
||||
} else {
|
||||
if (debugHistory)
|
||||
aapsLogger.debug(LTag.PUMP, getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntry: not null - " + medtronicUtil.gsonInstance.toJson(lastPumpHistoryEntry));
|
||||
aapsLogger.debug(LTag.PUMP, getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntry: not null - " + medtronicUtil.getGsonInstance().toJson(lastPumpHistoryEntry));
|
||||
medtronicHistoryData.setIsInInit(false);
|
||||
// medtronicHistoryData.setLastHistoryRecordTime(lastPumpHistoryEntry.atechDateTime);
|
||||
|
||||
|
@ -1204,12 +1211,12 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
//aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate);
|
||||
|
||||
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetHistoryData,
|
||||
lastPumpHistoryEntry, targetDate);
|
||||
Arrays.asList(lastPumpHistoryEntry, targetDate));
|
||||
|
||||
if (debugHistory)
|
||||
aapsLogger.debug(LTag.PUMP, "HST: After task");
|
||||
|
||||
PumpHistoryResult historyResult = (PumpHistoryResult) responseTask2.returnData;
|
||||
PumpHistoryResult historyResult = (PumpHistoryResult) responseTask2.getResult();
|
||||
|
||||
if (debugHistory)
|
||||
aapsLogger.debug(LTag.PUMP, "HST: History Result: " + historyResult.toString());
|
||||
|
@ -1226,7 +1233,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
sp.putLong(MedtronicConst.Statistics.LastPumpHistoryEntry, latestEntry.getAtechDateTime());
|
||||
|
||||
if (debugHistory)
|
||||
aapsLogger.debug(LTag.PUMP, "HST: History: valid=" + historyResult.validEntries.size() + ", unprocessed=" + historyResult.unprocessedEntries.size());
|
||||
aapsLogger.debug(LTag.PUMP, "HST: History: valid=" + historyResult.getValidEntries().size() + ", unprocessed=" + historyResult.getUnprocessedEntries().size());
|
||||
|
||||
this.medtronicHistoryData.addNewHistory(historyResult);
|
||||
this.medtronicHistoryData.filterNewEntries();
|
||||
|
@ -1281,7 +1288,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
switch (refreshType) {
|
||||
|
||||
case RemainingInsulin: {
|
||||
double remaining = medtronicPumpStatus.reservoirRemainingUnits;
|
||||
double remaining = medtronicPumpStatus.getReservoirRemainingUnits();
|
||||
int min;
|
||||
if (remaining > 50)
|
||||
min = 4 * 60;
|
||||
|
@ -1348,7 +1355,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.ReadTemporaryBasal);
|
||||
|
||||
if (responseTask.hasData()) {
|
||||
TempBasalPair tbr = (TempBasalPair) responseTask.returnData;
|
||||
TempBasalPair tbr = (TempBasalPair) responseTask.getResult();
|
||||
|
||||
// we sometimes get rate returned even if TBR is no longer running
|
||||
if (tbr.getDurationMinutes() == 0) {
|
||||
|
@ -1397,7 +1404,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
|
||||
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.CancelTBR);
|
||||
|
||||
Boolean response = (Boolean) responseTask2.returnData;
|
||||
Boolean response = (Boolean) responseTask2.getResult();
|
||||
|
||||
finishAction("TBR");
|
||||
|
||||
|
@ -1434,7 +1441,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
|
||||
@NonNull @Override
|
||||
public String serialNumber() {
|
||||
return medtronicPumpStatus.serialNumber;
|
||||
return medtronicPumpStatus.getSerialNumber();
|
||||
}
|
||||
|
||||
@NonNull @Override
|
||||
|
@ -1465,6 +1472,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
|
||||
BasalProfile basalProfile = convertProfileToMedtronicProfile(profile);
|
||||
|
||||
aapsLogger.debug("Basal Profile: " + basalProfile);
|
||||
|
||||
String profileInvalid = isProfileValid(basalProfile);
|
||||
|
||||
if (profileInvalid != null) {
|
||||
|
@ -1475,9 +1484,9 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
}
|
||||
|
||||
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetBasalProfileSTD,
|
||||
basalProfile);
|
||||
Arrays.asList(basalProfile));
|
||||
|
||||
Boolean response = (Boolean) responseTask.returnData;
|
||||
Boolean response = (Boolean) responseTask.getResult();
|
||||
|
||||
aapsLogger.info(LTag.PUMP, getLogPrefix() + "Basal Profile was set: " + response);
|
||||
|
||||
|
@ -1494,12 +1503,12 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
|||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
if (medtronicPumpStatus.maxBasal == null)
|
||||
if (medtronicPumpStatus.getMaxBasal() == null)
|
||||
return null;
|
||||
|
||||
for (BasalProfileEntry profileEntry : basalProfile.getEntries()) {
|
||||
|
||||
if (profileEntry.getRate() > medtronicPumpStatus.maxBasal) {
|
||||
if (profileEntry.getRate() > medtronicPumpStatus.getMaxBasal()) {
|
||||
stringBuilder.append(profileEntry.getStartTime().toString("HH:mm"));
|
||||
stringBuilder.append("=");
|
||||
stringBuilder.append(profileEntry.getRate());
|
||||
|
|
|
@ -80,8 +80,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
@Inject
|
||||
public void onInit() {
|
||||
// we can't do this in the constructor, as sp only gets injected after the constructor has returned
|
||||
medtronicPumpStatus.previousConnection = sp.getLong(
|
||||
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
|
||||
medtronicPumpStatus.setPreviousConnection(sp.getLong(
|
||||
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -136,7 +136,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
if (!canPreventTuneUp) {
|
||||
|
||||
long diff = System.currentTimeMillis() - medtronicPumpStatus.lastConnection;
|
||||
long diff = System.currentTimeMillis() - medtronicPumpStatus.getLastConnection();
|
||||
|
||||
if (diff > RILEYLINK_TIMEOUT) {
|
||||
serviceTaskExecutor.startTask(new WakeAndTuneTask(injector));
|
||||
|
@ -278,7 +278,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
for (List<Byte> frame : frames) {
|
||||
|
||||
byte[] frameData = MedtronicUtil.createByteArray(frame);
|
||||
byte[] frameData = medtronicUtil.createByteArray(frame);
|
||||
|
||||
// aapsLogger.debug(LTag.PUMPCOMM,"Frame {} data:\n{}", frameNr, ByteUtil.getCompactString(frameData));
|
||||
|
||||
|
@ -570,7 +570,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
try {
|
||||
PumpMessage response = sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
|
||||
|
||||
String check = checkResponseContent(response, commandType.commandDescription, commandType.expectedLength);
|
||||
String check = checkResponseContent(response, commandType.getCommandDescription(), commandType.getExpectedLength());
|
||||
|
||||
if (check == null) {
|
||||
|
||||
|
@ -632,11 +632,11 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
// PUMP SPECIFIC COMMANDS
|
||||
|
||||
public Float getRemainingInsulin() {
|
||||
public Double getRemainingInsulin() {
|
||||
|
||||
Object responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.GetRemainingInsulin);
|
||||
|
||||
return responseObject == null ? null : (Float) responseObject;
|
||||
return responseObject == null ? null : (Double) responseObject;
|
||||
}
|
||||
|
||||
|
||||
|
@ -677,7 +677,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
// aapsLogger.debug(LTag.PUMPCOMM,"1st Response: " + HexDump.toHexStringDisplayable(response.getRawContent()));
|
||||
// aapsLogger.debug(LTag.PUMPCOMM,"1st Response: " + HexDump.toHexStringDisplayable(response.getMessageBody().getTxData()));
|
||||
|
||||
String check = checkResponseContent(response, commandType.commandDescription, 1);
|
||||
String check = checkResponseContent(response, commandType.getCommandDescription(), 1);
|
||||
|
||||
byte[] data = null;
|
||||
|
||||
|
@ -695,7 +695,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
// aapsLogger.debug(LTag.PUMPCOMM,"{} Response: {}", runs,
|
||||
// HexDump.toHexStringDisplayable(response2.getMessageBody().getTxData()));
|
||||
|
||||
String check2 = checkResponseContent(response, commandType.commandDescription, 1);
|
||||
String check2 = checkResponseContent(response, commandType.getCommandDescription(), 1);
|
||||
|
||||
if (check2 == null) {
|
||||
|
||||
|
@ -765,12 +765,12 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
public ClockDTO getPumpTime() {
|
||||
|
||||
ClockDTO clockDTO = new ClockDTO();
|
||||
clockDTO.localDeviceTime = new LocalDateTime();
|
||||
clockDTO.setLocalDeviceTime(new LocalDateTime());
|
||||
|
||||
Object responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.GetRealTimeClock);
|
||||
|
||||
if (responseObject != null) {
|
||||
clockDTO.pumpTime = (LocalDateTime) responseObject;
|
||||
clockDTO.setPumpTime((LocalDateTime) responseObject);
|
||||
return clockDTO;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ class MedtronicConverter @Inject constructor(
|
|||
}
|
||||
|
||||
MedtronicCommandType.ReadTemporaryBasal -> {
|
||||
TempBasalPair(aapsLogger, rawContent) // 5
|
||||
TempBasalPair(aapsLogger, rawContent!!) // 5
|
||||
}
|
||||
|
||||
MedtronicCommandType.Settings_512 -> {
|
||||
|
@ -112,7 +112,7 @@ class MedtronicConverter @Inject constructor(
|
|||
batteryStatus.batteryStatusType = BatteryStatusDTO.BatteryStatusType.Unknown
|
||||
}
|
||||
if (rawData.size > 1) {
|
||||
var d: Double? = null
|
||||
var d: Double? //= null
|
||||
|
||||
// if response in 3 bytes then we add additional information
|
||||
d = if (rawData.size == 2) {
|
||||
|
@ -126,7 +126,7 @@ class MedtronicConverter @Inject constructor(
|
|||
return batteryStatus
|
||||
}
|
||||
|
||||
private fun decodeRemainingInsulin(rawData: ByteArray?): Float {
|
||||
private fun decodeRemainingInsulin(rawData: ByteArray?): Double {
|
||||
var startIdx = 0
|
||||
val pumpModel = medtronicUtil.medtronicPumpModel
|
||||
val strokes = pumpModel?.bolusStrokes ?: 10
|
||||
|
@ -134,11 +134,11 @@ class MedtronicConverter @Inject constructor(
|
|||
startIdx = 2
|
||||
}
|
||||
val reqLength = startIdx + 1
|
||||
var value = 0f
|
||||
var value = 0.0
|
||||
value = if (reqLength >= rawData!!.size) {
|
||||
rawData[startIdx] / (1.0f * strokes)
|
||||
rawData[startIdx] / (1.0 * strokes)
|
||||
} else {
|
||||
ByteUtil.toInt(rawData[startIdx], rawData[startIdx + 1]) / (1.0f * strokes)
|
||||
ByteUtil.toInt(rawData[startIdx], rawData[startIdx + 1]) / (1.0 * strokes)
|
||||
}
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Remaining insulin: $value")
|
||||
return value
|
||||
|
@ -208,7 +208,7 @@ class MedtronicConverter @Inject constructor(
|
|||
rd[settingIndexMaxBasal + 1].toInt())), PumpConfigurationGroup.Basal, map)
|
||||
addSettingToMap("CFG_BASE_CLOCK_MODE", if (rd[settingIndexTimeDisplayFormat].toInt() == 0) "12h" else "24h",
|
||||
PumpConfigurationGroup.General, map)
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel, MedtronicDeviceType.Medtronic_523andHigher)) {
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel!!, MedtronicDeviceType.Medtronic_523andHigher)) {
|
||||
addSettingToMap("PCFG_INSULIN_CONCENTRATION", "" + if (rd[9].toInt() == 0) 50 else 100, PumpConfigurationGroup.Insulin,
|
||||
map)
|
||||
// LOG.debug("Insulin concentration: " + rd[9]);
|
||||
|
@ -249,7 +249,7 @@ class MedtronicConverter @Inject constructor(
|
|||
addSettingToMap("PCFG_MM_SRESERVOIR_WARNING_POINT", "" + ByteUtil.asUINT8(rd[19]),
|
||||
PumpConfigurationGroup.Other, map)
|
||||
addSettingToMap("CFG_MM_KEYPAD_LOCKED", parseResultEnable(rd[20].toInt()), PumpConfigurationGroup.Other, map)
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel, MedtronicDeviceType.Medtronic_523andHigher)) {
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel!!, MedtronicDeviceType.Medtronic_523andHigher)) {
|
||||
addSettingToMap("PCFG_BOLUS_SCROLL_STEP_SIZE", "" + rd[21], PumpConfigurationGroup.Bolus, map)
|
||||
addSettingToMap("PCFG_CAPTURE_EVENT_ENABLE", parseResultEnable(rd[22].toInt()), PumpConfigurationGroup.Other, map)
|
||||
addSettingToMap("PCFG_OTHER_DEVICE_ENABLE", parseResultEnable(rd[23].toInt()), PumpConfigurationGroup.Other, map)
|
||||
|
@ -273,7 +273,7 @@ class MedtronicConverter @Inject constructor(
|
|||
|
||||
// 512
|
||||
private fun decodeInsulinActionSetting(ai: ByteArray, map: MutableMap<String, PumpSettingDTO>) {
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel, MedtronicDeviceType.Medtronic_512_712)) {
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel!!, MedtronicDeviceType.Medtronic_512_712)) {
|
||||
addSettingToMap("PCFG_INSULIN_ACTION_TYPE", if (ai[17].toInt() != 0) "Regular" else "Fast",
|
||||
PumpConfigurationGroup.Insulin, map)
|
||||
} else {
|
||||
|
@ -297,10 +297,10 @@ class MedtronicConverter @Inject constructor(
|
|||
}
|
||||
|
||||
private val settingIndexMaxBasal: Int
|
||||
private get() = if (is523orHigher()) 7 else 6
|
||||
get() = if (is523orHigher()) 7 else 6
|
||||
|
||||
private val settingIndexTimeDisplayFormat: Int
|
||||
private get() = if (is523orHigher()) 9 else 8
|
||||
get() = if (is523orHigher()) 9 else 8
|
||||
|
||||
private fun decodeMaxBolus(ai: ByteArray?): Double {
|
||||
return if (is523orHigher()) decodeBolusInsulin(ByteUtil.toInt(ai!![5], ai[6])) else decodeBolusInsulin(ByteUtil
|
||||
|
@ -308,7 +308,7 @@ class MedtronicConverter @Inject constructor(
|
|||
}
|
||||
|
||||
private fun is523orHigher(): Boolean {
|
||||
return MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel, MedtronicDeviceType.Medtronic_523andHigher)
|
||||
return MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel!!, MedtronicDeviceType.Medtronic_523andHigher)
|
||||
}
|
||||
|
||||
}
|
|
@ -38,8 +38,8 @@ abstract class MedtronicHistoryDecoder<T : MedtronicHistoryEntry?> : MedtronicHi
|
|||
private fun checkPage(page: RawHistoryPage, partial: Boolean): List<Byte> {
|
||||
val byteList: List<Byte> = ArrayList()
|
||||
|
||||
if (medtronicUtil!!.medtronicPumpModel == null) {
|
||||
aapsLogger!!.error(LTag.PUMPCOMM, "Device Type is not defined.")
|
||||
if (medtronicUtil.medtronicPumpModel == null) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "Device Type is not defined.")
|
||||
return byteList
|
||||
}
|
||||
return if (page.data.size != 1024) {
|
||||
|
@ -82,9 +82,9 @@ abstract class MedtronicHistoryDecoder<T : MedtronicHistoryEntry?> : MedtronicHi
|
|||
for ((key) in unknownOpCodes!!) {
|
||||
StringUtil.appendToStringBuilder(sb, "" + key, ", ")
|
||||
}
|
||||
aapsLogger!!.info(LTag.PUMPCOMM, "STATISTICS OF PUMP DECODE")
|
||||
aapsLogger.info(LTag.PUMPCOMM, "STATISTICS OF PUMP DECODE")
|
||||
if (unknownOpCodes!!.size > 0) {
|
||||
aapsLogger!!.warn(LTag.PUMPCOMM, "Unknown Op Codes: $sb")
|
||||
aapsLogger.warn(LTag.PUMPCOMM, "Unknown Op Codes: $sb")
|
||||
}
|
||||
for ((key, value) in mapStatistics!!) {
|
||||
sb = StringBuilder()
|
||||
|
@ -94,9 +94,9 @@ abstract class MedtronicHistoryDecoder<T : MedtronicHistoryEntry?> : MedtronicHi
|
|||
StringUtil.appendToStringBuilder(sb, key1, ", ")
|
||||
}
|
||||
val spaces = StringUtils.repeat(" ", 14 - key.name.length)
|
||||
aapsLogger!!.info(LTag.PUMPCOMM, String.format(Locale.ENGLISH, " %s%s - %d. Elements: %s", key.name, spaces, value.size, sb.toString()))
|
||||
aapsLogger.info(LTag.PUMPCOMM, String.format(Locale.ENGLISH, " %s%s - %d. Elements: %s", key.name, spaces, value.size, sb.toString()))
|
||||
} else {
|
||||
aapsLogger!!.info(LTag.PUMPCOMM, String.format(Locale.ENGLISH, " %s - %d", key.name, value.size))
|
||||
aapsLogger.info(LTag.PUMPCOMM, String.format(Locale.ENGLISH, " %s - %d", key.name, value.size))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
|
|||
if (!doNotProcess) {
|
||||
head = ByteArray(headLength - 1)
|
||||
for (i in 1 until headLength) {
|
||||
head!![i - 1] = listRawData!![i]!!
|
||||
head!![i - 1] = listRawData[i]
|
||||
}
|
||||
if (dateTimeLength > 0) {
|
||||
datetime = ByteArray(dateTimeLength)
|
||||
|
@ -99,7 +99,7 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
|
|||
var i = headLength + dateTimeLength
|
||||
var j = 0
|
||||
while (j < bodyLength) {
|
||||
body!![j] = listRawData!![i]!!
|
||||
body!![j] = listRawData[i]
|
||||
i++
|
||||
j++
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class RawHistoryPage(private val aapsLogger: AAPSLogger) {
|
|||
aapsLogger.error(LTag.PUMPBTCOMM, String.format(Locale.ENGLISH, "Stored CRC (%d) is different than calculated (%d), but ignored for now.", crcStored,
|
||||
crcCalculated))
|
||||
} else {
|
||||
if (MedtronicUtil.isLowLevelDebug()) aapsLogger.debug(LTag.PUMPBTCOMM, "CRC ok.")
|
||||
if (MedtronicUtil.isLowLevelDebug) aapsLogger.debug(LTag.PUMPBTCOMM, "CRC ok.")
|
||||
}
|
||||
return crcCalculated == crcStored
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
|||
return outList
|
||||
}
|
||||
do {
|
||||
val opCode: Int = dataClear[counter]!!.toInt()
|
||||
val opCode: Int = dataClear[counter].toInt()
|
||||
var special = false
|
||||
incompletePacket = false
|
||||
var skippedRecords = false
|
||||
|
@ -69,7 +69,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
|||
}
|
||||
val entryType = getByCode(opCode.toByte())
|
||||
val pe = PumpHistoryEntry()
|
||||
pe.setEntryType(medtronicUtil!!.medtronicPumpModel, entryType!!)
|
||||
pe.setEntryType(medtronicUtil.medtronicPumpModel!!, entryType!!)
|
||||
pe.offset = counter
|
||||
counter++
|
||||
if (counter >= 1022) {
|
||||
|
@ -91,7 +91,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
|||
}
|
||||
special = true
|
||||
} else {
|
||||
for (j in 0 until entryType.getTotalLength(medtronicUtil.medtronicPumpModel) - 1) {
|
||||
for (j in 0 until entryType.getTotalLength(medtronicUtil.medtronicPumpModel!!) - 1) {
|
||||
try {
|
||||
listRawData.add(dataClear[counter])
|
||||
counter++
|
||||
|
@ -111,7 +111,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
|||
if (pe.entryType === PumpHistoryEntryType.UnknownBasePacket) {
|
||||
pe.opCode = opCode.toByte()
|
||||
}
|
||||
if (entryType.getHeadLength(medtronicUtil!!.medtronicPumpModel) == 0) special = true
|
||||
if (entryType.getHeadLength(medtronicUtil!!.medtronicPumpModel!!) == 0) special = true
|
||||
pe.setData(listRawData as List<Byte>, special)
|
||||
val decoded = decodeRecord(pe)
|
||||
if (decoded === RecordDecodeStatus.OK || decoded === RecordDecodeStatus.Ignored) {
|
||||
|
@ -235,7 +235,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
|||
val offset = body!![0] * 1000 * 30 * 60
|
||||
var rate: Float? = null
|
||||
val index = entry.head!![0].toInt()
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel, MedtronicDeviceType.Medtronic_523andHigher)) {
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel!!, MedtronicDeviceType.Medtronic_523andHigher)) {
|
||||
rate = body[1] * 0.025f
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
|||
val body = entry.body!!
|
||||
val dto = BolusWizardDTO()
|
||||
var bolusStrokes = 10.0f
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil!!.medtronicPumpModel, MedtronicDeviceType.Medtronic_523andHigher)) {
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil!!.medtronicPumpModel!!, MedtronicDeviceType.Medtronic_523andHigher)) {
|
||||
// https://github.com/ps2/minimed_rf/blob/master/lib/minimed_rf/log_entries/bolus_wizard.rb#L102
|
||||
bolusStrokes = 40.0f
|
||||
dto.carbs = ((body[1] and 0x0c.toByte()).toInt() shl 6) + body[0]
|
||||
|
@ -263,19 +263,19 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
|||
// carb_ratio (?) = (((self.body[2] & 0x07) << 8) + self.body[3]) /
|
||||
// 10.0s
|
||||
dto.insulinSensitivity = body[4].toFloat()
|
||||
dto.bgTargetLow = body[5] as Int
|
||||
dto.bgTargetHigh = body[14] as Int
|
||||
dto.bgTargetLow = body[5].toInt()
|
||||
dto.bgTargetHigh = body[14].toInt()
|
||||
dto.correctionEstimate = (((body[9] and 0x38).toInt() shl 5) + body[6]) / bolusStrokes
|
||||
dto.foodEstimate = ((body[7].toInt() shl 8) + body[8]) / bolusStrokes
|
||||
dto.unabsorbedInsulin = ((body[10].toInt() shl 8) + body[11]) / bolusStrokes
|
||||
dto.bolusTotal = ((body[12].toInt() shl 8) + body[13]) / bolusStrokes
|
||||
} else {
|
||||
dto.bloodGlucose = (body.get(1) and 0x0F).toInt() shl 8 or entry.head!!.get(0).toInt()
|
||||
dto.carbs = body.get(0) as Int
|
||||
dto.carbs = body.get(0).toInt()
|
||||
dto.carbRatio = body.get(2).toFloat()
|
||||
dto.insulinSensitivity = body.get(3).toFloat()
|
||||
dto.bgTargetLow = body.get(4) as Int
|
||||
dto.bgTargetHigh = body.get(12) as Int
|
||||
dto.bgTargetLow = body.get(4).toInt()
|
||||
dto.bgTargetHigh = body.get(12).toInt()
|
||||
dto.bolusTotal = body.get(11) / bolusStrokes
|
||||
dto.foodEstimate = body.get(6) / bolusStrokes
|
||||
dto.unabsorbedInsulin = body.get(9) / bolusStrokes
|
||||
|
@ -359,7 +359,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
|||
private fun decodeBolus(entry: PumpHistoryEntry) {
|
||||
val bolus = BolusDTO()
|
||||
val data = entry.head!!
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil.getMedtronicPumpModel(), MedtronicDeviceType.Medtronic_523andHigher)) {
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel!!, MedtronicDeviceType.Medtronic_523andHigher)) {
|
||||
bolus.requestedAmount = ByteUtil.toInt(data.get(0), data.get(1)) / 40.0
|
||||
bolus.deliveredAmount = ByteUtil.toInt(data.get(2), data.get(3)) / 40.0
|
||||
bolus.insulinOnBoard = ByteUtil.toInt(data.get(4), data.get(5)) / 40.0
|
||||
|
@ -369,8 +369,8 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
|||
bolus.deliveredAmount = ByteUtil.asUINT8(data.get(1)) / 10.0
|
||||
bolus.duration = ByteUtil.asUINT8(data.get(2)) * 30
|
||||
}
|
||||
bolus.bolusType = if (bolus.duration != null && bolus.duration > 0) PumpBolusType.Extended else PumpBolusType.Normal
|
||||
bolus.setAtechDateTime(entry.atechDateTime!!)
|
||||
bolus.bolusType = if (bolus.duration != null && bolus.duration!! > 0) PumpBolusType.Extended else PumpBolusType.Normal
|
||||
bolus.atechDateTime = entry.atechDateTime!!
|
||||
entry.addDecodedData("Object", bolus)
|
||||
entry.displayableValue = bolus.displayableValue
|
||||
}
|
||||
|
@ -404,10 +404,10 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
|||
// tbrDuration.getHead()[0],
|
||||
// (ByteUtil.asUINT8(tbrRate.getDatetime()[4]) >> 3) == 0);
|
||||
val tbr = TempBasalPair(
|
||||
tbrRate!!.head!!.get(0),
|
||||
tbrRate!!.body!!.get(0),
|
||||
tbrRate.head!!.get(0),
|
||||
tbrRate.body!!.get(0),
|
||||
tbrDuration!!.head!!.get(0).toInt(),
|
||||
ByteUtil.asUINT8(tbrRate!!.datetime!!.get(4)) shr 3 == 0)
|
||||
ByteUtil.asUINT8(tbrRate.datetime!!.get(4)) shr 3 == 0)
|
||||
|
||||
// System.out.println("TBR: amount=" + tbr.getInsulinRate() + ", duration=" + tbr.getDurationMinutes()
|
||||
// // + " min. Packed: " + tbr.getValue()
|
||||
|
@ -464,13 +464,13 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
|||
}
|
||||
|
||||
private fun fix2DigitYear(year: Int): Int {
|
||||
var year = year
|
||||
year += if (year > 90) {
|
||||
var yearInternal = year
|
||||
yearInternal += if (yearInternal > 90) {
|
||||
1900
|
||||
} else {
|
||||
2000
|
||||
}
|
||||
return year
|
||||
return yearInternal
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -35,16 +35,16 @@ class PumpHistoryEntry : MedtronicHistoryEntry() {
|
|||
field = value
|
||||
}
|
||||
|
||||
fun setEntryType(medtronicDeviceType: MedtronicDeviceType?, entryType: PumpHistoryEntryType) {
|
||||
fun setEntryType(medtronicDeviceType: MedtronicDeviceType, entryType: PumpHistoryEntryType) {
|
||||
this.entryType = entryType
|
||||
sizes[0] = entryType.getHeadLength(medtronicDeviceType)
|
||||
sizes[1] = entryType.dateLength
|
||||
sizes[2] = entryType.getBodyLength(medtronicDeviceType)
|
||||
if (this.entryType != null && atechDateTime != null) setPumpId()
|
||||
if (this.entryType != null && atechDateTime != null) generatePumpId()
|
||||
}
|
||||
|
||||
private fun setPumpId() {
|
||||
pumpId = entryType!!.code + atechDateTime!! * 1000L
|
||||
private fun generatePumpId() : Long {
|
||||
return entryType!!.code + atechDateTime!! * 1000L
|
||||
}
|
||||
|
||||
override val toStringStart: String
|
||||
|
@ -105,7 +105,7 @@ class PumpHistoryEntry : MedtronicHistoryEntry() {
|
|||
|
||||
override var pumpId: Long? = null
|
||||
get() {
|
||||
setPumpId()
|
||||
field = generatePumpId()
|
||||
return field
|
||||
}
|
||||
set(pumpId) {
|
||||
|
|
|
@ -212,7 +212,7 @@ enum class PumpHistoryEntryType // implements CodeEnum
|
|||
private constructor(opCode: Byte, group: PumpHistoryEntryGroup) : this(opCode, null, group, 2, 5, 0) {}
|
||||
private constructor(opCode: Byte, group: PumpHistoryEntryGroup, head: Int, date: Int, body: Int) : this(opCode, null, group, head, date, body) {}
|
||||
|
||||
fun getTotalLength(medtronicDeviceType: MedtronicDeviceType?): Int {
|
||||
fun getTotalLength(medtronicDeviceType: MedtronicDeviceType): Int {
|
||||
return if (hasSpecialRules) {
|
||||
getHeadLength(medtronicDeviceType) + getBodyLength(medtronicDeviceType) + dateLength
|
||||
} else {
|
||||
|
@ -220,10 +220,6 @@ enum class PumpHistoryEntryType // implements CodeEnum
|
|||
}
|
||||
}
|
||||
|
||||
// private fun hasSpecialRules(): Boolean {
|
||||
// return hasSpecialRules
|
||||
// }
|
||||
|
||||
fun addSpecialRuleHead(rule: SpecialRule) {
|
||||
if (isEmpty(specialRulesHead)) {
|
||||
specialRulesHead = ArrayList()
|
||||
|
@ -244,7 +240,7 @@ enum class PumpHistoryEntryType // implements CodeEnum
|
|||
// return description ?: name
|
||||
// }
|
||||
|
||||
fun getHeadLength(medtronicDeviceType: MedtronicDeviceType?): Int {
|
||||
fun getHeadLength(medtronicDeviceType: MedtronicDeviceType): Int {
|
||||
return if (hasSpecialRules) {
|
||||
if (isNotEmpty(specialRulesHead)) {
|
||||
determineSizeByRule(medtronicDeviceType, headLength, specialRulesHead)
|
||||
|
@ -256,7 +252,7 @@ enum class PumpHistoryEntryType // implements CodeEnum
|
|||
}
|
||||
}
|
||||
|
||||
fun getBodyLength(medtronicDeviceType: MedtronicDeviceType?): Int {
|
||||
fun getBodyLength(medtronicDeviceType: MedtronicDeviceType): Int {
|
||||
return if (hasSpecialRules) {
|
||||
if (isNotEmpty(specialRulesBody)) {
|
||||
determineSizeByRule(medtronicDeviceType, bodyLength, specialRulesBody)
|
||||
|
@ -277,7 +273,7 @@ enum class PumpHistoryEntryType // implements CodeEnum
|
|||
}
|
||||
|
||||
// byte[] dh = { 2, 3 };
|
||||
private fun determineSizeByRule(medtronicDeviceType: MedtronicDeviceType?, defaultValue: Int, rules: List<SpecialRule>?): Int {
|
||||
private fun determineSizeByRule(medtronicDeviceType: MedtronicDeviceType, defaultValue: Int, rules: List<SpecialRule>?): Int {
|
||||
var size = defaultValue
|
||||
for (rule in rules!!) {
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicDeviceType, rule.deviceType)) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import info.nightscout.androidaps.logging.AAPSLogger
|
|||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
/**
|
||||
* History page contains data, sorted from newest to oldest (0=newest..n=oldest)
|
||||
|
@ -18,9 +19,11 @@ class PumpHistoryResult(private val aapsLogger: AAPSLogger, searchEntry: PumpHis
|
|||
private val searchEntry: PumpHistoryEntry? = null
|
||||
private var searchDate: Long? = null
|
||||
private var searchType = SearchType.None
|
||||
@JvmField var unprocessedEntries: List<PumpHistoryEntry?>? = null
|
||||
@JvmField var validEntries: MutableList<PumpHistoryEntry?>?
|
||||
fun addHistoryEntries(entries: List<PumpHistoryEntry?>?, page: Int) {
|
||||
var unprocessedEntries: List<PumpHistoryEntry> = ArrayList()
|
||||
var validEntries: MutableList<PumpHistoryEntry> = ArrayList()
|
||||
|
||||
|
||||
fun addHistoryEntries(entries: List<PumpHistoryEntry>, page: Int) {
|
||||
unprocessedEntries = entries
|
||||
//aapsLogger.debug(LTag.PUMPCOMM,"PumpHistoryResult. Unprocessed entries: {}", MedtronicUtil.getGsonInstance().toJson(entries));
|
||||
processEntries()
|
||||
|
@ -32,7 +35,7 @@ class PumpHistoryResult(private val aapsLogger: AAPSLogger, searchEntry: PumpHis
|
|||
Collections.reverse(unprocessedEntries)
|
||||
when (searchType) {
|
||||
SearchType.None -> //aapsLogger.debug(LTag.PUMPCOMM,"PE. None search");
|
||||
validEntries!!.addAll(unprocessedEntries!!)
|
||||
validEntries.addAll(unprocessedEntries)
|
||||
|
||||
SearchType.LastEntry -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "PE. Last entry search")
|
||||
|
@ -40,27 +43,27 @@ class PumpHistoryResult(private val aapsLogger: AAPSLogger, searchEntry: PumpHis
|
|||
//Collections.sort(this.unprocessedEntries, new PumpHistoryEntry.Comparator());
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "PE. PumpHistoryResult. Search entry date: " + searchEntry!!.atechDateTime)
|
||||
val date = searchEntry.atechDateTime
|
||||
for (unprocessedEntry in unprocessedEntries!!) {
|
||||
if (unprocessedEntry!!.equals(searchEntry)) {
|
||||
for (unprocessedEntry in unprocessedEntries) {
|
||||
if (unprocessedEntry.equals(searchEntry)) {
|
||||
//aapsLogger.debug(LTag.PUMPCOMM,"PE. Item found {}.", unprocessedEntry);
|
||||
isSearchFinished = true
|
||||
break
|
||||
}
|
||||
|
||||
//aapsLogger.debug(LTag.PUMPCOMM,"PE. Entry {} added.", unprocessedEntry);
|
||||
validEntries!!.add(unprocessedEntry)
|
||||
validEntries.add(unprocessedEntry)
|
||||
}
|
||||
}
|
||||
|
||||
SearchType.Date -> {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "PE. Date search: Search date: " + searchDate)
|
||||
for (unprocessedEntry in unprocessedEntries!!) {
|
||||
if (unprocessedEntry!!.atechDateTime == null || unprocessedEntry.atechDateTime == 0L) {
|
||||
for (unprocessedEntry in unprocessedEntries) {
|
||||
if (unprocessedEntry.atechDateTime == null || unprocessedEntry.atechDateTime == 0L) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "PE. PumpHistoryResult. Search entry date: Entry with no date: $unprocessedEntry")
|
||||
continue
|
||||
}
|
||||
if (unprocessedEntry.isAfter(searchDate!!)) {
|
||||
validEntries!!.add(unprocessedEntry)
|
||||
validEntries.add(unprocessedEntry)
|
||||
} else {
|
||||
// aapsLogger.debug(LTag.PUMPCOMM,"PE. PumpHistoryResult. Not after.. Unprocessed Entry [year={},entry={}]",
|
||||
// DateTimeUtil.getYear(unprocessedEntry.atechDateTime), unprocessedEntry);
|
||||
|
@ -85,35 +88,19 @@ class PumpHistoryResult(private val aapsLogger: AAPSLogger, searchEntry: PumpHis
|
|||
", searchType=" + searchType + //
|
||||
", searchFinished=" + isSearchFinished + //
|
||||
"]"
|
||||
}// PumpHistoryEntry pumpHistoryEntry = this.validEntries.get(0);
|
||||
//
|
||||
// if (pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.EndResultTotals)
|
||||
// return pumpHistoryEntry;
|
||||
// else
|
||||
// return this.validEntries.get(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return latest entry (entry with highest date time)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
val latestEntry: PumpHistoryEntry?
|
||||
get() = if (validEntries == null || validEntries!!.size == 0) null else {
|
||||
validEntries!![0]
|
||||
// PumpHistoryEntry pumpHistoryEntry = this.validEntries.get(0);
|
||||
//
|
||||
// if (pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.EndResultTotals)
|
||||
// return pumpHistoryEntry;
|
||||
// else
|
||||
// return this.validEntries.get(1);
|
||||
}
|
||||
get() = if (validEntries.size == 0) null else validEntries[0]
|
||||
|
||||
val isSearchRequired: Boolean
|
||||
get() = searchType != SearchType.None
|
||||
|
||||
fun getValidEntries(): List<PumpHistoryEntry?>? {
|
||||
return validEntries
|
||||
}
|
||||
// val isSearchRequired: Boolean
|
||||
// get() = searchType != SearchType.None
|
||||
|
||||
|
||||
internal enum class SearchType {
|
||||
None, //
|
||||
|
@ -139,6 +126,6 @@ class PumpHistoryResult(private val aapsLogger: AAPSLogger, searchEntry: PumpHis
|
|||
}
|
||||
|
||||
// this.unprocessedEntries = new ArrayList<>();
|
||||
validEntries = ArrayList()
|
||||
//validEntries = ArrayList()
|
||||
}
|
||||
}
|
|
@ -67,13 +67,13 @@ class PumpMessage : RLMessage {
|
|||
|
||||
override fun getTxData(): ByteArray {
|
||||
var rval = ByteUtil.concat(byteArrayOf(packetType!!.value), address)
|
||||
rval = ByteUtil.concat(rval, commandType!!.getCommandCode())
|
||||
rval = ByteUtil.concat(rval, commandType!!.commandCode)
|
||||
rval = ByteUtil.concat(rval, messageBody!!.txData)
|
||||
return rval
|
||||
}
|
||||
|
||||
val contents: ByteArray
|
||||
get() = ByteUtil.concat(byteArrayOf(commandType!!.getCommandCode()), messageBody!!.txData)// length is not always correct so, we check whole array if we have
|
||||
get() = ByteUtil.concat(byteArrayOf(commandType!!.commandCode), messageBody!!.txData)// length is not always correct so, we check whole array if we have
|
||||
// data, after length
|
||||
|
||||
// check if displayed length is invalid
|
||||
|
@ -91,7 +91,7 @@ class PumpMessage : RLMessage {
|
|||
val data = messageBody!!.txData
|
||||
var length = ByteUtil.asUINT8(data!![0]) // length is not always correct so, we check whole array if we have
|
||||
// data, after length
|
||||
val originalLength = length
|
||||
//val originalLength = length
|
||||
|
||||
// check if displayed length is invalid
|
||||
if (length > data.size - 1) {
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui;
|
||||
|
||||
import dagger.android.HasAndroidInjector;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 6/14/18.
|
||||
*/
|
||||
public class MedtronicUIComm {
|
||||
|
||||
private final HasAndroidInjector injector;
|
||||
private final AAPSLogger aapsLogger;
|
||||
private final MedtronicUtil medtronicUtil;
|
||||
private final MedtronicCommunicationManager medtronicCommunicationManager;
|
||||
private final MedtronicUIPostprocessor medtronicUIPostprocessor;
|
||||
|
||||
public MedtronicUIComm(
|
||||
HasAndroidInjector injector,
|
||||
AAPSLogger aapsLogger,
|
||||
MedtronicUtil medtronicUtil,
|
||||
MedtronicUIPostprocessor medtronicUIPostprocessor,
|
||||
MedtronicCommunicationManager medtronicCommunicationManager
|
||||
) {
|
||||
this.injector = injector;
|
||||
this.aapsLogger = aapsLogger;
|
||||
this.medtronicUtil = medtronicUtil;
|
||||
this.medtronicUIPostprocessor = medtronicUIPostprocessor;
|
||||
this.medtronicCommunicationManager = medtronicCommunicationManager;
|
||||
}
|
||||
|
||||
public synchronized MedtronicUITask executeCommand(MedtronicCommandType commandType, Object... parameters) {
|
||||
|
||||
aapsLogger.info(LTag.PUMP, "Execute Command: " + commandType.name());
|
||||
|
||||
MedtronicUITask task = new MedtronicUITask(injector, commandType, parameters);
|
||||
|
||||
medtronicUtil.setCurrentCommand(commandType);
|
||||
|
||||
task.execute(medtronicCommunicationManager);
|
||||
|
||||
if (!task.isReceived()) {
|
||||
aapsLogger.warn(LTag.PUMP, "Reply not received for " + commandType);
|
||||
}
|
||||
|
||||
task.postProcess(medtronicUIPostprocessor);
|
||||
|
||||
return task;
|
||||
|
||||
}
|
||||
|
||||
public int getInvalidResponsesCount() {
|
||||
return medtronicCommunicationManager.getNotConnectedCount();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil
|
||||
|
||||
/**
|
||||
* Created by andy on 6/14/18.
|
||||
*/
|
||||
class MedtronicUIComm(
|
||||
private val injector: HasAndroidInjector,
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val medtronicUtil: MedtronicUtil,
|
||||
private val medtronicUIPostprocessor: MedtronicUIPostprocessor,
|
||||
private val medtronicCommunicationManager: MedtronicCommunicationManager
|
||||
) {
|
||||
|
||||
fun executeCommand(commandType: MedtronicCommandType): MedtronicUITask {
|
||||
return executeCommand(commandType, null)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun executeCommand(commandType: MedtronicCommandType, parameters: List<Any>?): MedtronicUITask {
|
||||
|
||||
aapsLogger.info(LTag.PUMP, "Execute Command: " + commandType.name)
|
||||
val task = MedtronicUITask(injector, commandType, parameters)
|
||||
medtronicUtil.setCurrentCommand(commandType)
|
||||
task.execute(medtronicCommunicationManager)
|
||||
|
||||
if (!task.isReceived) {
|
||||
aapsLogger.warn(LTag.PUMP, "Reply not received for $commandType")
|
||||
}
|
||||
|
||||
task.postProcess(medtronicUIPostprocessor)
|
||||
return task
|
||||
}
|
||||
|
||||
val invalidResponsesCount: Int
|
||||
get() = medtronicCommunicationManager.notConnectedCount
|
||||
|
||||
}
|
|
@ -1,252 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui;
|
||||
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BatteryStatusDTO;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.ClockDTO;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.PumpSettingDTO;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BasalProfileStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicNotificationType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicUIResponseType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
|
||||
|
||||
/**
|
||||
* Created by andy on 6/15/18.
|
||||
*/
|
||||
|
||||
@Singleton
|
||||
public class MedtronicUIPostprocessor {
|
||||
|
||||
private final AAPSLogger aapsLogger;
|
||||
private final RxBusWrapper rxBus;
|
||||
private final ResourceHelper resourceHelper;
|
||||
private final MedtronicUtil medtronicUtil;
|
||||
private final MedtronicPumpStatus medtronicPumpStatus;
|
||||
private final MedtronicPumpPlugin medtronicPumpPlugin;
|
||||
|
||||
@Inject
|
||||
public MedtronicUIPostprocessor(
|
||||
AAPSLogger aapsLogger,
|
||||
RxBusWrapper rxBus,
|
||||
ResourceHelper resourceHelper,
|
||||
MedtronicUtil medtronicUtil,
|
||||
MedtronicPumpStatus medtronicPumpStatus,
|
||||
MedtronicPumpPlugin medtronicPumpPlugin) {
|
||||
this.aapsLogger = aapsLogger;
|
||||
this.rxBus = rxBus;
|
||||
this.resourceHelper = resourceHelper;
|
||||
this.medtronicUtil = medtronicUtil;
|
||||
this.medtronicPumpStatus = medtronicPumpStatus;
|
||||
this.medtronicPumpPlugin = medtronicPumpPlugin;
|
||||
}
|
||||
|
||||
|
||||
// this is mostly intended for command that return certain statuses (Remaining Insulin, ...), and
|
||||
// where responses won't be directly used
|
||||
void postProcessData(MedtronicUITask uiTask) {
|
||||
|
||||
switch (uiTask.commandType) {
|
||||
|
||||
case SetBasalProfileSTD: {
|
||||
Boolean response = (Boolean) uiTask.returnData;
|
||||
|
||||
if (response) {
|
||||
BasalProfile basalProfile = (BasalProfile) uiTask.getParameter(0);
|
||||
|
||||
medtronicPumpStatus.basalsByHour = basalProfile.getProfilesByHour(medtronicPumpPlugin.getPumpDescription().getPumpType());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GetBasalProfileSTD: {
|
||||
BasalProfile basalProfile = (BasalProfile) uiTask.returnData;
|
||||
|
||||
try {
|
||||
Double[] profilesByHour = basalProfile.getProfilesByHour(medtronicPumpPlugin.getPumpDescription().getPumpType());
|
||||
|
||||
if (profilesByHour != null) {
|
||||
medtronicPumpStatus.basalsByHour = profilesByHour;
|
||||
medtronicPumpStatus.basalProfileStatus = BasalProfileStatus.ProfileOK;
|
||||
} else {
|
||||
uiTask.responseType = MedtronicUIResponseType.Error;
|
||||
uiTask.errorDescription = "No profile found.";
|
||||
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Basal Profile was NOT valid. [%s]", basalProfile.basalProfileToStringError()));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Basal Profile was returned, but was invalid. [%s]", basalProfile.basalProfileToStringError()));
|
||||
uiTask.responseType = MedtronicUIResponseType.Error;
|
||||
uiTask.errorDescription = "No profile found.";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetBolus: {
|
||||
medtronicPumpStatus.lastBolusAmount = uiTask.getDoubleFromParameters(0);
|
||||
medtronicPumpStatus.lastBolusTime = new Date();
|
||||
}
|
||||
break;
|
||||
|
||||
case GetRemainingInsulin: {
|
||||
medtronicPumpStatus.reservoirRemainingUnits = (Float) uiTask.returnData;
|
||||
}
|
||||
break;
|
||||
|
||||
case CancelTBR: {
|
||||
medtronicPumpStatus.tempBasalStart = null;
|
||||
medtronicPumpStatus.tempBasalAmount = null;
|
||||
medtronicPumpStatus.tempBasalLength = null;
|
||||
}
|
||||
break;
|
||||
|
||||
case GetRealTimeClock: {
|
||||
processTime(uiTask);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetRealTimeClock: {
|
||||
boolean response = (Boolean) uiTask.returnData;
|
||||
|
||||
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "New time was %s set.", response ? "" : "NOT"));
|
||||
|
||||
if (response) {
|
||||
medtronicUtil.getPumpTime().timeDifference = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case GetBatteryStatus: {
|
||||
BatteryStatusDTO batteryStatusDTO = (BatteryStatusDTO) uiTask.returnData;
|
||||
|
||||
medtronicPumpStatus.batteryRemaining = batteryStatusDTO.getCalculatedPercent(medtronicPumpStatus.batteryType);
|
||||
|
||||
if (batteryStatusDTO.voltage != null) {
|
||||
medtronicPumpStatus.batteryVoltage = batteryStatusDTO.voltage;
|
||||
}
|
||||
|
||||
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "BatteryStatus: %s", batteryStatusDTO.toString()));
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case PumpModel: {
|
||||
if (medtronicPumpStatus.medtronicDeviceType != medtronicUtil.getMedtronicPumpModel()) {
|
||||
aapsLogger.warn(LTag.PUMP, "Configured pump is different then pump detected !");
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpTypeNotSame, resourceHelper, rxBus);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Settings_512:
|
||||
case Settings: {
|
||||
postProcessSettings(uiTask);
|
||||
}
|
||||
break;
|
||||
|
||||
// no postprocessing
|
||||
|
||||
default:
|
||||
break;
|
||||
//aapsLogger.error(LTag.PUMP, "Post-processing not implemented for {}.", uiTask.commandType.name());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void processTime(MedtronicUITask uiTask) {
|
||||
|
||||
ClockDTO clockDTO = (ClockDTO) uiTask.returnData;
|
||||
|
||||
Duration dur = new Duration(clockDTO.pumpTime.toDateTime(DateTimeZone.UTC),
|
||||
clockDTO.localDeviceTime.toDateTime(DateTimeZone.UTC));
|
||||
|
||||
clockDTO.timeDifference = (int) dur.getStandardSeconds();
|
||||
|
||||
medtronicUtil.setPumpTime(clockDTO);
|
||||
|
||||
aapsLogger.debug(LTag.PUMP, "Pump Time: " + clockDTO.localDeviceTime + ", DeviceTime=" + clockDTO.pumpTime + //
|
||||
", diff: " + dur.getStandardSeconds() + " s");
|
||||
|
||||
// if (dur.getStandardMinutes() >= 10) {
|
||||
// if (isLogEnabled())
|
||||
// LOG.warn("Pump clock needs update, pump time: " + clockDTO.pumpTime.toString("HH:mm:ss") + " (difference: "
|
||||
// + dur.getStandardSeconds() + " s)");
|
||||
// sendNotification(MedtronicNotificationType.PumpWrongTimeUrgent);
|
||||
// } else if (dur.getStandardMinutes() >= 4) {
|
||||
// if (isLogEnabled())
|
||||
// LOG.warn("Pump clock needs update, pump time: " + clockDTO.pumpTime.toString("HH:mm:ss") + " (difference: "
|
||||
// + dur.getStandardSeconds() + " s)");
|
||||
// sendNotification(MedtronicNotificationType.PumpWrongTimeNormal);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void postProcessSettings(MedtronicUITask uiTask) {
|
||||
|
||||
Map<String, PumpSettingDTO> settings = (Map<String, PumpSettingDTO>) uiTask.returnData;
|
||||
|
||||
medtronicUtil.setSettings(settings);
|
||||
|
||||
PumpSettingDTO checkValue;
|
||||
|
||||
medtronicPumpPlugin.getRileyLinkService().verifyConfiguration();
|
||||
|
||||
// check profile
|
||||
if (!"Yes".equals(settings.get("PCFG_BASAL_PROFILES_ENABLED").value)) {
|
||||
aapsLogger.error(LTag.PUMP, "Basal profiles are not enabled on pump.");
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpBasalProfilesNotEnabled, resourceHelper, rxBus);
|
||||
|
||||
} else {
|
||||
checkValue = settings.get("PCFG_ACTIVE_BASAL_PROFILE");
|
||||
|
||||
if (!"STD".equals(checkValue.value)) {
|
||||
aapsLogger.error("Basal profile set on pump is incorrect (must be STD).");
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpIncorrectBasalProfileSelected, resourceHelper, rxBus);
|
||||
}
|
||||
}
|
||||
|
||||
// TBR
|
||||
|
||||
checkValue = settings.get("PCFG_TEMP_BASAL_TYPE");
|
||||
|
||||
if (!"Units".equals(checkValue.value)) {
|
||||
aapsLogger.error("Wrong TBR type set on pump (must be Absolute).");
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongTBRTypeSet, resourceHelper, rxBus);
|
||||
}
|
||||
|
||||
// MAXes
|
||||
|
||||
checkValue = settings.get("PCFG_MAX_BOLUS");
|
||||
|
||||
if (!MedtronicUtil.isSame(Double.parseDouble(checkValue.value), medtronicPumpStatus.maxBolus)) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Wrong Max Bolus set on Pump (current=%s, required=%.2f).", checkValue.value, medtronicPumpStatus.maxBolus));
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongMaxBolusSet, resourceHelper, rxBus, medtronicPumpStatus.maxBolus);
|
||||
}
|
||||
|
||||
checkValue = settings.get("PCFG_MAX_BASAL");
|
||||
|
||||
if (!MedtronicUtil.isSame(Double.parseDouble(checkValue.value), medtronicPumpStatus.maxBasal)) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Wrong Max Basal set on Pump (current=%s, required=%.2f).", checkValue.value, medtronicPumpStatus.maxBasal));
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongMaxBasalSet, resourceHelper, rxBus, medtronicPumpStatus.maxBasal);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui
|
||||
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BatteryStatusDTO
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.ClockDTO
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.PumpSettingDTO
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BasalProfileStatus
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicNotificationType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicUIResponseType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import org.joda.time.DateTimeZone
|
||||
import org.joda.time.Duration
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Created by andy on 6/15/18.
|
||||
*/
|
||||
@Singleton
|
||||
class MedtronicUIPostprocessor @Inject constructor(
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val rxBus: RxBusWrapper,
|
||||
private val resourceHelper: ResourceHelper,
|
||||
private val medtronicUtil: MedtronicUtil,
|
||||
private val medtronicPumpStatus: MedtronicPumpStatus,
|
||||
private val medtronicPumpPlugin: MedtronicPumpPlugin) {
|
||||
|
||||
// this is mostly intended for command that return certain statuses (Remaining Insulin, ...), and
|
||||
// where responses won't be directly used
|
||||
fun postProcessData(uiTask: MedtronicUITask) {
|
||||
when (uiTask.commandType) {
|
||||
MedtronicCommandType.SetBasalProfileSTD -> {
|
||||
val response = uiTask.result as Boolean?
|
||||
if (response!!) {
|
||||
val basalProfile = uiTask.getParameter(0) as BasalProfile
|
||||
aapsLogger.debug("D: basal profile returned after set: $basalProfile")
|
||||
|
||||
//var desc: PumpDescription = medtronicPumpPlugin.getP.getPumpDescription()
|
||||
|
||||
medtronicPumpStatus.basalsByHour = basalProfile.getProfilesByHour(medtronicPumpPlugin.pumpDescription.pumpType)
|
||||
}
|
||||
}
|
||||
|
||||
MedtronicCommandType.GetBasalProfileSTD -> {
|
||||
val basalProfile = uiTask.result as BasalProfile?
|
||||
|
||||
//aapsLogger.debug("D: basal profile on read: " + basalProfile);
|
||||
try {
|
||||
val profilesByHour = basalProfile!!.getProfilesByHour(medtronicPumpPlugin.pumpDescription.pumpType)
|
||||
if (profilesByHour != null) {
|
||||
medtronicPumpStatus.basalsByHour = profilesByHour
|
||||
medtronicPumpStatus.basalProfileStatus = BasalProfileStatus.ProfileOK
|
||||
//aapsLogger.debug("D: basal profile on read: basalsByHour: " + BasalProfile.getProfilesByHourToString(medtronicPumpStatus.basalsByHour));
|
||||
} else {
|
||||
uiTask.responseType = MedtronicUIResponseType.Error
|
||||
uiTask.errorDescription = "No profile found."
|
||||
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Basal Profile was NOT valid. [%s]", basalProfile.basalProfileToStringError()))
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Basal Profile was returned, but was invalid. [%s]", basalProfile!!.basalProfileToStringError()))
|
||||
uiTask.responseType = MedtronicUIResponseType.Error
|
||||
uiTask.errorDescription = "No profile found."
|
||||
}
|
||||
}
|
||||
|
||||
MedtronicCommandType.SetBolus -> {
|
||||
medtronicPumpStatus.lastBolusAmount = uiTask.getDoubleFromParameters(0)
|
||||
medtronicPumpStatus.lastBolusTime = Date()
|
||||
}
|
||||
|
||||
MedtronicCommandType.GetRemainingInsulin -> {
|
||||
medtronicPumpStatus.reservoirRemainingUnits = uiTask.result as Double
|
||||
}
|
||||
|
||||
MedtronicCommandType.CancelTBR -> {
|
||||
medtronicPumpStatus.tempBasalStart = null
|
||||
medtronicPumpStatus.tempBasalAmount = null
|
||||
medtronicPumpStatus.tempBasalLength = null
|
||||
}
|
||||
|
||||
MedtronicCommandType.GetRealTimeClock -> {
|
||||
processTime(uiTask)
|
||||
}
|
||||
|
||||
MedtronicCommandType.SetRealTimeClock -> {
|
||||
val response = uiTask.result as Boolean
|
||||
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "New time was %s set.", if (response) "" else "NOT"))
|
||||
if (response) {
|
||||
medtronicUtil.pumpTime!!.timeDifference = 0
|
||||
}
|
||||
}
|
||||
|
||||
MedtronicCommandType.GetBatteryStatus -> {
|
||||
val batteryStatusDTO = uiTask.result as BatteryStatusDTO?
|
||||
medtronicPumpStatus.batteryRemaining = batteryStatusDTO!!.getCalculatedPercent(medtronicPumpStatus.batteryType)
|
||||
if (batteryStatusDTO.voltage != null) {
|
||||
medtronicPumpStatus.batteryVoltage = batteryStatusDTO.voltage
|
||||
}
|
||||
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "BatteryStatus: %s", batteryStatusDTO.toString()))
|
||||
}
|
||||
|
||||
MedtronicCommandType.PumpModel -> {
|
||||
if (medtronicPumpStatus.medtronicDeviceType !== medtronicUtil.medtronicPumpModel) {
|
||||
aapsLogger.warn(LTag.PUMP, "Configured pump is different then pump detected !")
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpTypeNotSame, resourceHelper, rxBus)
|
||||
}
|
||||
}
|
||||
|
||||
MedtronicCommandType.Settings_512,
|
||||
MedtronicCommandType.Settings -> {
|
||||
postProcessSettings(uiTask)
|
||||
}
|
||||
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processTime(uiTask: MedtronicUITask) {
|
||||
val clockDTO = uiTask.result as ClockDTO?
|
||||
val dur = Duration(clockDTO!!.pumpTime!!.toDateTime(DateTimeZone.UTC),
|
||||
clockDTO.localDeviceTime!!.toDateTime(DateTimeZone.UTC))
|
||||
clockDTO.timeDifference = dur.standardSeconds.toInt()
|
||||
medtronicUtil.pumpTime = clockDTO
|
||||
aapsLogger.debug(LTag.PUMP, "Pump Time: " + clockDTO.localDeviceTime + ", DeviceTime=" + clockDTO.pumpTime + //
|
||||
", diff: " + dur.standardSeconds + " s")
|
||||
|
||||
// if (dur.getStandardMinutes() >= 10) {
|
||||
// if (isLogEnabled())
|
||||
// LOG.warn("Pump clock needs update, pump time: " + clockDTO.pumpTime.toString("HH:mm:ss") + " (difference: "
|
||||
// + dur.getStandardSeconds() + " s)");
|
||||
// sendNotification(MedtronicNotificationType.PumpWrongTimeUrgent);
|
||||
// } else if (dur.getStandardMinutes() >= 4) {
|
||||
// if (isLogEnabled())
|
||||
// LOG.warn("Pump clock needs update, pump time: " + clockDTO.pumpTime.toString("HH:mm:ss") + " (difference: "
|
||||
// + dur.getStandardSeconds() + " s)");
|
||||
// sendNotification(MedtronicNotificationType.PumpWrongTimeNormal);
|
||||
// }
|
||||
}
|
||||
|
||||
private fun postProcessSettings(uiTask: MedtronicUITask) {
|
||||
val settings = uiTask.result as Map<String, PumpSettingDTO>?
|
||||
medtronicUtil.settings = settings
|
||||
var checkValue: PumpSettingDTO?
|
||||
medtronicPumpPlugin.rileyLinkService!!.verifyConfiguration()
|
||||
|
||||
// check profile
|
||||
if ("Yes" != settings!!["PCFG_BASAL_PROFILES_ENABLED"]!!.value) {
|
||||
aapsLogger.error(LTag.PUMP, "Basal profiles are not enabled on pump.")
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpBasalProfilesNotEnabled, resourceHelper, rxBus)
|
||||
} else {
|
||||
checkValue = settings["PCFG_ACTIVE_BASAL_PROFILE"]
|
||||
if ("STD" != checkValue!!.value) {
|
||||
aapsLogger.error("Basal profile set on pump is incorrect (must be STD).")
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpIncorrectBasalProfileSelected, resourceHelper, rxBus)
|
||||
}
|
||||
}
|
||||
|
||||
// TBR
|
||||
checkValue = settings["PCFG_TEMP_BASAL_TYPE"]
|
||||
if ("Units" != checkValue!!.value) {
|
||||
aapsLogger.error("Wrong TBR type set on pump (must be Absolute).")
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongTBRTypeSet, resourceHelper, rxBus)
|
||||
}
|
||||
|
||||
// MAXes
|
||||
checkValue = settings["PCFG_MAX_BOLUS"]
|
||||
if (!MedtronicUtil.isSame(checkValue!!.value.toDouble(), medtronicPumpStatus.maxBolus!!)) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Wrong Max Bolus set on Pump (current=%s, required=%.2f).", checkValue.value, medtronicPumpStatus.maxBolus))
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongMaxBolusSet, resourceHelper, rxBus, medtronicPumpStatus.maxBolus)
|
||||
}
|
||||
checkValue = settings["PCFG_MAX_BASAL"]
|
||||
if (!MedtronicUtil.isSame(checkValue!!.value.toDouble(), medtronicPumpStatus.maxBasal!!)) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Wrong Max Basal set on Pump (current=%s, required=%.2f).", checkValue.value, medtronicPumpStatus.maxBasal))
|
||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongMaxBasalSet, resourceHelper, rxBus, medtronicPumpStatus.maxBasal)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,234 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.HasAndroidInjector;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState;
|
||||
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.TempBasalPair;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicUIResponseType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicPumpValuesChanged;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 6/14/18.
|
||||
*/
|
||||
|
||||
public class MedtronicUITask {
|
||||
|
||||
@Inject RxBusWrapper rxBus;
|
||||
@Inject AAPSLogger aapsLogger;
|
||||
@Inject MedtronicPumpStatus medtronicPumpStatus;
|
||||
@Inject MedtronicUtil medtronicUtil;
|
||||
|
||||
private final HasAndroidInjector injector;
|
||||
|
||||
public MedtronicCommandType commandType;
|
||||
public Object returnData;
|
||||
String errorDescription;
|
||||
// boolean invalid = false;
|
||||
private Object[] parameters;
|
||||
// private boolean received;
|
||||
MedtronicUIResponseType responseType;
|
||||
|
||||
|
||||
public MedtronicUITask(HasAndroidInjector injector, MedtronicCommandType commandType) {
|
||||
this.injector = injector;
|
||||
this.injector.androidInjector().inject(this);
|
||||
this.commandType = commandType;
|
||||
}
|
||||
|
||||
|
||||
public MedtronicUITask(HasAndroidInjector injector, MedtronicCommandType commandType, Object... parameters) {
|
||||
this.injector = injector;
|
||||
this.injector.androidInjector().inject(this);
|
||||
this.commandType = commandType;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
|
||||
public void execute(MedtronicCommunicationManager communicationManager) {
|
||||
|
||||
aapsLogger.debug(LTag.PUMP, "MedtronicUITask: @@@ In execute. " + commandType);
|
||||
|
||||
switch (commandType) {
|
||||
case PumpModel: {
|
||||
returnData = communicationManager.getPumpModel();
|
||||
}
|
||||
break;
|
||||
|
||||
case GetBasalProfileSTD: {
|
||||
returnData = communicationManager.getBasalProfile();
|
||||
}
|
||||
break;
|
||||
|
||||
case GetRemainingInsulin: {
|
||||
returnData = communicationManager.getRemainingInsulin();
|
||||
}
|
||||
break;
|
||||
|
||||
case GetRealTimeClock: {
|
||||
returnData = communicationManager.getPumpTime();
|
||||
medtronicUtil.setPumpTime(null);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetRealTimeClock: {
|
||||
returnData = communicationManager.setPumpTime();
|
||||
}
|
||||
break;
|
||||
|
||||
case GetBatteryStatus: {
|
||||
returnData = communicationManager.getRemainingBattery();
|
||||
}
|
||||
break;
|
||||
|
||||
case SetTemporaryBasal: {
|
||||
TempBasalPair tbr = getTBRSettings();
|
||||
if (tbr != null) {
|
||||
returnData = communicationManager.setTBR(tbr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ReadTemporaryBasal: {
|
||||
returnData = communicationManager.getTemporaryBasal();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case Settings:
|
||||
case Settings_512: {
|
||||
returnData = communicationManager.getPumpSettings();
|
||||
}
|
||||
break;
|
||||
|
||||
case SetBolus: {
|
||||
Double amount = getDoubleFromParameters(0);
|
||||
|
||||
if (amount != null)
|
||||
returnData = communicationManager.setBolus(amount);
|
||||
}
|
||||
break;
|
||||
|
||||
case CancelTBR: {
|
||||
returnData = communicationManager.cancelTBR();
|
||||
}
|
||||
break;
|
||||
|
||||
case SetBasalProfileSTD:
|
||||
case SetBasalProfileA: {
|
||||
BasalProfile profile = (BasalProfile) parameters[0];
|
||||
|
||||
returnData = communicationManager.setBasalProfile(profile);
|
||||
}
|
||||
break;
|
||||
|
||||
case GetHistoryData: {
|
||||
returnData = communicationManager.getPumpHistory((PumpHistoryEntry) parameters[0],
|
||||
(LocalDateTime) parameters[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
aapsLogger.warn(LTag.PUMP, String.format(Locale.ENGLISH, "This commandType is not supported (yet) - %s.", commandType));
|
||||
// invalid = true;
|
||||
responseType = MedtronicUIResponseType.Invalid;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (responseType == null) {
|
||||
if (returnData == null) {
|
||||
errorDescription = communicationManager.getErrorResponse();
|
||||
this.responseType = MedtronicUIResponseType.Error;
|
||||
} else {
|
||||
this.responseType = MedtronicUIResponseType.Data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private TempBasalPair getTBRSettings() {
|
||||
return new TempBasalPair(getDoubleFromParameters(0), //
|
||||
false, //
|
||||
getIntegerFromParameters(1));
|
||||
}
|
||||
|
||||
|
||||
private Float getFloatFromParameters(int index) {
|
||||
return (Float) parameters[index];
|
||||
}
|
||||
|
||||
|
||||
Double getDoubleFromParameters(int index) {
|
||||
return (Double) parameters[index];
|
||||
}
|
||||
|
||||
|
||||
private Integer getIntegerFromParameters(int index) {
|
||||
return (Integer) parameters[index];
|
||||
}
|
||||
|
||||
|
||||
public Object getResult() {
|
||||
return returnData;
|
||||
}
|
||||
|
||||
|
||||
public boolean isReceived() {
|
||||
return (returnData != null || errorDescription != null);
|
||||
}
|
||||
|
||||
|
||||
void postProcess(MedtronicUIPostprocessor postprocessor) {
|
||||
|
||||
aapsLogger.debug(LTag.PUMP, "MedtronicUITask: @@@ In execute. " + commandType);
|
||||
|
||||
if (responseType == MedtronicUIResponseType.Data) {
|
||||
postprocessor.postProcessData(this);
|
||||
}
|
||||
|
||||
if (responseType == MedtronicUIResponseType.Invalid) {
|
||||
rxBus.send(new EventRileyLinkDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
|
||||
"Unsupported command in MedtronicUITask"));
|
||||
} else if (responseType == MedtronicUIResponseType.Error) {
|
||||
rxBus.send(new EventRileyLinkDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
|
||||
errorDescription));
|
||||
} else {
|
||||
rxBus.send(new EventMedtronicPumpValuesChanged());
|
||||
medtronicPumpStatus.setLastCommunicationToNow();
|
||||
}
|
||||
|
||||
medtronicUtil.setCurrentCommand(null);
|
||||
}
|
||||
|
||||
|
||||
public boolean hasData() {
|
||||
return (responseType == MedtronicUIResponseType.Data);
|
||||
}
|
||||
|
||||
|
||||
Object getParameter(int index) {
|
||||
return parameters[index];
|
||||
}
|
||||
|
||||
|
||||
public MedtronicUIResponseType getResponseType() {
|
||||
return this.responseType;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState
|
||||
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.TempBasalPair
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicUIResponseType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicPumpValuesChanged
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil
|
||||
import org.joda.time.LocalDateTime
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Created by andy on 6/14/18.
|
||||
*/
|
||||
class MedtronicUITask {
|
||||
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var medtronicPumpStatus: MedtronicPumpStatus
|
||||
@Inject lateinit var medtronicUtil: MedtronicUtil
|
||||
|
||||
private val injector: HasAndroidInjector
|
||||
var commandType: MedtronicCommandType
|
||||
var result: Any? = null
|
||||
var errorDescription: String? = null
|
||||
var parameters: List<Any?>? = null
|
||||
var responseType: MedtronicUIResponseType? = null
|
||||
|
||||
constructor(injector: HasAndroidInjector, commandType: MedtronicCommandType) {
|
||||
this.injector = injector
|
||||
this.injector.androidInjector().inject(this)
|
||||
this.commandType = commandType
|
||||
}
|
||||
|
||||
constructor(injector: HasAndroidInjector, commandType: MedtronicCommandType, parameters: List<Any>?) {
|
||||
this.injector = injector
|
||||
this.injector.androidInjector().inject(this)
|
||||
this.commandType = commandType
|
||||
this.parameters = parameters //as Array<Any>
|
||||
}
|
||||
|
||||
fun execute(communicationManager: MedtronicCommunicationManager) {
|
||||
aapsLogger.debug(LTag.PUMP, "MedtronicUITask: @@@ In execute. $commandType")
|
||||
when (commandType) {
|
||||
MedtronicCommandType.PumpModel -> {
|
||||
result = communicationManager.pumpModel
|
||||
}
|
||||
|
||||
MedtronicCommandType.GetBasalProfileSTD -> {
|
||||
result = communicationManager.basalProfile
|
||||
}
|
||||
|
||||
MedtronicCommandType.GetRemainingInsulin -> {
|
||||
result = communicationManager.remainingInsulin
|
||||
}
|
||||
|
||||
MedtronicCommandType.GetRealTimeClock -> {
|
||||
result = communicationManager.pumpTime
|
||||
medtronicUtil.pumpTime = null
|
||||
}
|
||||
|
||||
MedtronicCommandType.SetRealTimeClock -> {
|
||||
result = communicationManager.setPumpTime()
|
||||
}
|
||||
|
||||
MedtronicCommandType.GetBatteryStatus -> {
|
||||
result = communicationManager.remainingBattery
|
||||
}
|
||||
|
||||
MedtronicCommandType.SetTemporaryBasal -> {
|
||||
val tbr = tBRSettings
|
||||
if (tbr != null) {
|
||||
result = communicationManager.setTBR(tbr)
|
||||
}
|
||||
}
|
||||
|
||||
MedtronicCommandType.ReadTemporaryBasal -> {
|
||||
result = communicationManager.temporaryBasal
|
||||
}
|
||||
|
||||
MedtronicCommandType.Settings, MedtronicCommandType.Settings_512 -> {
|
||||
result = communicationManager.pumpSettings
|
||||
}
|
||||
|
||||
MedtronicCommandType.SetBolus -> {
|
||||
val amount = getDoubleFromParameters(0)
|
||||
if (amount != null) result = communicationManager.setBolus(amount)
|
||||
}
|
||||
|
||||
MedtronicCommandType.CancelTBR -> {
|
||||
result = communicationManager.cancelTBR()
|
||||
}
|
||||
|
||||
MedtronicCommandType.SetBasalProfileSTD, MedtronicCommandType.SetBasalProfileA -> {
|
||||
val profile = parameters!![0] as BasalProfile
|
||||
result = communicationManager.setBasalProfile(profile)
|
||||
}
|
||||
|
||||
MedtronicCommandType.GetHistoryData -> {
|
||||
result = communicationManager.getPumpHistory(parameters!![0] as PumpHistoryEntry?,
|
||||
parameters!![1] as LocalDateTime?)
|
||||
}
|
||||
|
||||
else -> {
|
||||
aapsLogger.warn(LTag.PUMP, String.format(Locale.ENGLISH, "This commandType is not supported (yet) - %s.", commandType))
|
||||
// invalid = true;
|
||||
responseType = MedtronicUIResponseType.Invalid
|
||||
}
|
||||
}
|
||||
if (responseType == null) {
|
||||
if (result == null) {
|
||||
errorDescription = communicationManager.errorResponse
|
||||
responseType = MedtronicUIResponseType.Error
|
||||
} else {
|
||||
responseType = MedtronicUIResponseType.Data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
private val tBRSettings: TempBasalPair
|
||||
private get() = TempBasalPair(getDoubleFromParameters(0), //
|
||||
false, //
|
||||
getIntegerFromParameters(1))
|
||||
|
||||
private fun getFloatFromParameters(index: Int): Float {
|
||||
return parameters!![index] as Float
|
||||
}
|
||||
|
||||
fun getDoubleFromParameters(index: Int): Double {
|
||||
return parameters!![index] as Double
|
||||
}
|
||||
|
||||
private fun getIntegerFromParameters(index: Int): Int {
|
||||
return parameters!![index] as Int
|
||||
}
|
||||
|
||||
val isReceived: Boolean
|
||||
get() = result != null || errorDescription != null
|
||||
|
||||
fun postProcess(postprocessor: MedtronicUIPostprocessor) {
|
||||
aapsLogger.debug(LTag.PUMP, "MedtronicUITask: @@@ In execute. $commandType")
|
||||
if (responseType === MedtronicUIResponseType.Data) {
|
||||
postprocessor.postProcessData(this)
|
||||
}
|
||||
if (responseType === MedtronicUIResponseType.Invalid) {
|
||||
rxBus.send(EventRileyLinkDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
|
||||
"Unsupported command in MedtronicUITask"))
|
||||
} else if (responseType === MedtronicUIResponseType.Error) {
|
||||
rxBus.send(EventRileyLinkDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
|
||||
errorDescription))
|
||||
} else {
|
||||
rxBus.send(EventMedtronicPumpValuesChanged())
|
||||
medtronicPumpStatus.setLastCommunicationToNow()
|
||||
}
|
||||
medtronicUtil.setCurrentCommand(null)
|
||||
}
|
||||
|
||||
fun hasData(): Boolean {
|
||||
return responseType === MedtronicUIResponseType.Data
|
||||
}
|
||||
|
||||
fun getParameter(index: Int): Any? {
|
||||
return parameters!![index]
|
||||
}
|
||||
|
||||
}
|
|
@ -580,7 +580,8 @@ public class MedtronicHistoryData {
|
|||
|
||||
|
||||
private void uploadCareportalEvent(long date, DetailedBolusInfo.EventType event) {
|
||||
pumpSync.insertTherapyEventIfNewWithTimestamp(date, event, null, null, medtronicPumpStatus.pumpType, medtronicPumpStatus.serialNumber);
|
||||
pumpSync.insertTherapyEventIfNewWithTimestamp(date, event, null, null,
|
||||
medtronicPumpStatus.getPumpType(), medtronicPumpStatus.getSerialNumber());
|
||||
}
|
||||
|
||||
private void processTDDs(List<PumpHistoryEntry> tddsIn) {
|
||||
|
@ -972,7 +973,7 @@ public class MedtronicHistoryData {
|
|||
|
||||
detailedBolusInfo.setBolusTimestamp(tryToGetByLocalTime(bolus.getAtechDateTime()));
|
||||
detailedBolusInfo.setPumpType(PumpType.MEDTRONIC_512_712); // TODO grab real model
|
||||
detailedBolusInfo.setPumpSerial(medtronicPumpStatus.serialNumber);
|
||||
detailedBolusInfo.setPumpSerial(medtronicPumpStatus.getSerialNumber());
|
||||
detailedBolusInfo.setBolusPumpId(bolus.getPumpId());
|
||||
detailedBolusInfo.insulin = bolusDTO.getDeliveredAmount();
|
||||
|
||||
|
@ -1046,7 +1047,7 @@ public class MedtronicHistoryData {
|
|||
if (doubleBolusDebug)
|
||||
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: addCarbsFromEstimate: Bolus=%s, BolusWizardDTO=%s", bolus, bolusWizard));
|
||||
|
||||
detailedBolusInfo.carbs = bolusWizard.carbs;
|
||||
detailedBolusInfo.carbs = bolusWizard.getCarbs();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1373,7 +1374,7 @@ public class MedtronicHistoryData {
|
|||
|
||||
// returns oldest time in history, with calculated time difference between pump and phone, minus 5 minutes
|
||||
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "Oldest entry: %d, pumpTimeDifference=%d, newDt=%s, currentTime=%s, differenceMin=%d", dt,
|
||||
this.pumpTime.timeDifference, oldestEntryTime, now, minutes.getMinutes()));
|
||||
this.pumpTime.getTimeDifference(), oldestEntryTime, now, minutes.getMinutes()));
|
||||
|
||||
return minutes.getMinutes();
|
||||
}
|
||||
|
@ -1480,7 +1481,7 @@ public class MedtronicHistoryData {
|
|||
aapsLogger.debug(LTag.PUMP, "processLastBasalProfileChange. item found, setting new basalProfileLocally: " + newProfile);
|
||||
BasalProfile basalProfile = (BasalProfile) newProfile.getDecodedData().get("Object");
|
||||
|
||||
mdtPumpStatus.basalsByHour = basalProfile.getProfilesByHour(pumpType);
|
||||
mdtPumpStatus.setBasalsByHour( basalProfile.getProfilesByHour(pumpType));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,18 +55,18 @@ class BasalProfile {
|
|||
}
|
||||
|
||||
private fun setRawData(data: ByteArray): Boolean {
|
||||
var data: ByteArray? = data
|
||||
if (data == null) {
|
||||
var dataInternal: ByteArray? = data
|
||||
if (dataInternal == null) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "setRawData: buffer is null!")
|
||||
return false
|
||||
}
|
||||
|
||||
// if we have just one entry through all day it looks like just length 1
|
||||
if (data.size == 1) {
|
||||
data = MedtronicUtil.createByteArray(data[0], 0.toByte(), 0.toByte())
|
||||
if (dataInternal.size == 1) {
|
||||
dataInternal = byteArrayOf(dataInternal[0], 0, 0)
|
||||
}
|
||||
if (data!!.size == MAX_RAW_DATA_SIZE) {
|
||||
rawData = data
|
||||
if (dataInternal.size == MAX_RAW_DATA_SIZE) {
|
||||
rawData = dataInternal
|
||||
} else {
|
||||
val len = Math.min(MAX_RAW_DATA_SIZE, data.size)
|
||||
rawData = ByteArray(MAX_RAW_DATA_SIZE)
|
||||
|
@ -233,10 +233,10 @@ class BasalProfile {
|
|||
// return this.mRawData;
|
||||
}
|
||||
|
||||
fun getProfilesByHour(pumpType: PumpType?): Array<Double?> {
|
||||
var entries: List<BasalProfileEntry>? = null
|
||||
fun getProfilesByHour(pumpType: PumpType): Array<Double> {
|
||||
var entriesCopy: List<BasalProfileEntry>? = null
|
||||
try {
|
||||
entries = entries
|
||||
entriesCopy = entries
|
||||
} catch (ex: Exception) {
|
||||
aapsLogger.error(LTag.PUMPCOMM, "=============================================================================")
|
||||
aapsLogger.error(LTag.PUMPCOMM, " Error generating entries. Ex.: $ex", ex)
|
||||
|
@ -245,40 +245,43 @@ class BasalProfile {
|
|||
|
||||
//FabricUtil.createEvent("MedtronicBasalProfileGetByHourError", null);
|
||||
}
|
||||
if (entries == null || entries.size == 0) {
|
||||
if (entriesCopy == null || entriesCopy.size == 0) {
|
||||
val basalByHour = arrayOfNulls<Double>(24)
|
||||
for (i in 0..23) {
|
||||
basalByHour[i] = 0.0
|
||||
}
|
||||
return basalByHour
|
||||
return basalByHour as Array<Double>
|
||||
}
|
||||
val basalByHour = arrayOfNulls<Double>(24)
|
||||
for (i in entries.indices) {
|
||||
val current = entries[i]
|
||||
for (i in entriesCopy.indices) {
|
||||
val current = entriesCopy[i]
|
||||
var currentTime = if (current.startTime_raw % 2 == 0) current.startTime_raw.toInt() else current.startTime_raw - 1
|
||||
currentTime = currentTime * 30 / 60
|
||||
var lastHour: Int
|
||||
lastHour = if (i + 1 == entries.size) {
|
||||
lastHour = if (i + 1 == entriesCopy.size) {
|
||||
24
|
||||
} else {
|
||||
val basalProfileEntry = entries[i + 1]
|
||||
val basalProfileEntry = entriesCopy[i + 1]
|
||||
val rawTime = if (basalProfileEntry.startTime_raw % 2 == 0) basalProfileEntry.startTime_raw.toInt() else basalProfileEntry.startTime_raw - 1
|
||||
rawTime * 30 / 60
|
||||
}
|
||||
|
||||
// System.out.println("Current time: " + currentTime + " Next Time: " + lastHour);
|
||||
for (j in currentTime until lastHour) {
|
||||
if (pumpType == null) basalByHour[j] = current.rate else basalByHour[j] = pumpType.determineCorrectBasalSize(current.rate)
|
||||
if (pumpType == null)
|
||||
basalByHour[j] = current.rate
|
||||
else
|
||||
basalByHour[j] = pumpType.determineCorrectBasalSize(current.rate)
|
||||
}
|
||||
}
|
||||
return basalByHour
|
||||
return basalByHour as Array<Double>
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return basalProfileToString()
|
||||
}
|
||||
|
||||
fun verify(pumpType: PumpType?): Boolean {
|
||||
fun verify(pumpType: PumpType): Boolean {
|
||||
try {
|
||||
entries
|
||||
} catch (ex: Exception) {
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BatteryType;
|
||||
|
||||
/**
|
||||
* Created by andy on 6/14/18.
|
||||
*/
|
||||
|
||||
public class BatteryStatusDTO {
|
||||
|
||||
@Expose
|
||||
public BatteryStatusType batteryStatusType;
|
||||
@Expose
|
||||
public Double voltage;
|
||||
|
||||
public boolean extendedDataReceived = false;
|
||||
|
||||
|
||||
public int getCalculatedPercent(BatteryType batteryType) {
|
||||
if (voltage == null || batteryType == BatteryType.None) {
|
||||
return (batteryStatusType == BatteryStatusType.Low || batteryStatusType == BatteryStatusType.Unknown) ? 18 : 70;
|
||||
}
|
||||
|
||||
double percent = (voltage - batteryType.lowVoltage) / (batteryType.highVoltage - batteryType.lowVoltage);
|
||||
|
||||
int percentInt = (int) (percent * 100.0d);
|
||||
|
||||
if (percentInt < 0)
|
||||
percentInt = 1;
|
||||
|
||||
if (percentInt > 100)
|
||||
percentInt = 100;
|
||||
|
||||
return percentInt;
|
||||
}
|
||||
|
||||
|
||||
@NonNull public String toString() {
|
||||
return String.format(Locale.ENGLISH, "BatteryStatusDTO [voltage=%.2f, alkaline=%d, lithium=%d, niZn=%d, nimh=%d]",
|
||||
voltage == null ? 0.0f : voltage,
|
||||
getCalculatedPercent(BatteryType.Alkaline),
|
||||
getCalculatedPercent(BatteryType.Lithium),
|
||||
getCalculatedPercent(BatteryType.NiZn),
|
||||
getCalculatedPercent(BatteryType.NiMH));
|
||||
}
|
||||
|
||||
|
||||
public enum BatteryStatusType {
|
||||
Normal,
|
||||
Low,
|
||||
Unknown
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto
|
||||
|
||||
import com.google.gson.annotations.Expose
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BatteryType
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by andy on 6/14/18.
|
||||
*/
|
||||
class BatteryStatusDTO {
|
||||
|
||||
@Expose
|
||||
var batteryStatusType: BatteryStatusType? = null
|
||||
@Expose
|
||||
var voltage: Double? = null
|
||||
|
||||
var extendedDataReceived = false
|
||||
|
||||
|
||||
fun getCalculatedPercent(batteryType: BatteryType): Int {
|
||||
if (voltage == null || batteryType === BatteryType.None) {
|
||||
return if (batteryStatusType == BatteryStatusType.Low || batteryStatusType == BatteryStatusType.Unknown) 18 else 70
|
||||
}
|
||||
val percent = (voltage!! - batteryType.lowVoltage) / (batteryType.highVoltage - batteryType.lowVoltage)
|
||||
var percentInt = (percent * 100.0).toInt()
|
||||
if (percentInt < 0) percentInt = 1
|
||||
if (percentInt > 100) percentInt = 100
|
||||
return percentInt
|
||||
}
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
return String.format(Locale.ENGLISH, "BatteryStatusDTO [voltage=%.2f, alkaline=%d, lithium=%d, niZn=%d, nimh=%d]",
|
||||
if (voltage == null) 0.0f else voltage,
|
||||
getCalculatedPercent(BatteryType.Alkaline),
|
||||
getCalculatedPercent(BatteryType.Lithium),
|
||||
getCalculatedPercent(BatteryType.NiZn),
|
||||
getCalculatedPercent(BatteryType.NiMH))
|
||||
}
|
||||
|
||||
enum class BatteryStatusType {
|
||||
Normal,
|
||||
Low,
|
||||
Unknown
|
||||
}
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpBolusType;
|
||||
|
||||
/**
|
||||
* Application: GGC - GNU Gluco Control
|
||||
* Plug-in: Pump Tool (support for Pump devices)
|
||||
* <p>
|
||||
* See AUTHORS for copyright information.
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
|
||||
* version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* <p>
|
||||
* Filename: BolusDTO Description: Bolus DTO
|
||||
* <p>
|
||||
* Author: Andy {andy@atech-software.com}
|
||||
*/
|
||||
|
||||
public class BolusDTO extends PumpTimeStampedRecord {
|
||||
|
||||
@Expose
|
||||
private Double requestedAmount;
|
||||
@Expose
|
||||
private Double deliveredAmount;
|
||||
@Expose
|
||||
private Double immediateAmount; // when Multiwave this is used
|
||||
@Expose
|
||||
private Integer duration;
|
||||
@Expose
|
||||
private PumpBolusType bolusType;
|
||||
private Double insulinOnBoard;
|
||||
|
||||
|
||||
public BolusDTO() {
|
||||
// this.decimalPrecission = 2;
|
||||
}
|
||||
|
||||
|
||||
public Double getRequestedAmount() {
|
||||
return requestedAmount;
|
||||
}
|
||||
|
||||
|
||||
public void setRequestedAmount(Double requestedAmount) {
|
||||
this.requestedAmount = requestedAmount;
|
||||
}
|
||||
|
||||
|
||||
public Double getDeliveredAmount() {
|
||||
return deliveredAmount;
|
||||
}
|
||||
|
||||
|
||||
public void setDeliveredAmount(Double deliveredAmount) {
|
||||
this.deliveredAmount = deliveredAmount;
|
||||
}
|
||||
|
||||
|
||||
public Integer getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
|
||||
public void setDuration(Integer duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
|
||||
public PumpBolusType getBolusType() {
|
||||
return bolusType;
|
||||
}
|
||||
|
||||
|
||||
public void setBolusType(PumpBolusType bolusType) {
|
||||
this.bolusType = bolusType;
|
||||
}
|
||||
|
||||
|
||||
public Double getInsulinOnBoard() {
|
||||
return insulinOnBoard;
|
||||
}
|
||||
|
||||
|
||||
public void setInsulinOnBoard(Double insulinOnBoard) {
|
||||
this.insulinOnBoard = insulinOnBoard;
|
||||
}
|
||||
|
||||
|
||||
private String getDurationString() {
|
||||
int minutes = this.duration;
|
||||
|
||||
int h = minutes / 60;
|
||||
|
||||
minutes -= (h * 60);
|
||||
|
||||
return StringUtil.getLeadingZero(h, 2) + ":" + StringUtil.getLeadingZero(minutes, 2);
|
||||
}
|
||||
|
||||
|
||||
public String getValue() {
|
||||
if ((bolusType == PumpBolusType.Normal) || (bolusType == PumpBolusType.Audio)) {
|
||||
return getFormattedDecimal(this.deliveredAmount);
|
||||
} else if (bolusType == PumpBolusType.Extended) {
|
||||
return String.format("AMOUNT_SQUARE=%s;DURATION=%s", getFormattedDecimal(this.deliveredAmount),
|
||||
getDurationString());
|
||||
} else {
|
||||
return String.format("AMOUNT=%s;AMOUNT_SQUARE=%s;DURATION=%s", getFormattedDecimal(this.immediateAmount),
|
||||
getFormattedDecimal(this.deliveredAmount), getDurationString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getDisplayableValue() {
|
||||
String value = getValue();
|
||||
|
||||
value = value.replace("AMOUNT_SQUARE=", "Amount Square: ");
|
||||
value = value.replace("AMOUNT=", "Amount: ");
|
||||
value = value.replace("DURATION=", "Duration: ");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public Double getImmediateAmount() {
|
||||
return immediateAmount;
|
||||
}
|
||||
|
||||
|
||||
public void setImmediateAmount(Double immediateAmount) {
|
||||
this.immediateAmount = immediateAmount;
|
||||
}
|
||||
|
||||
|
||||
public String getFormattedDecimal(double value) {
|
||||
return StringUtil.getFormatedValueUS(value, 2);
|
||||
}
|
||||
|
||||
|
||||
public String getBolusKey() {
|
||||
return "Bolus_" + this.bolusType.name();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BolusDTO [type=" + bolusType.name() + ", " + getValue() + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto
|
||||
|
||||
import com.google.gson.annotations.Expose
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpBolusType
|
||||
|
||||
/**
|
||||
* Application: GGC - GNU Gluco Control
|
||||
* Plug-in: Pump Tool (support for Pump devices)
|
||||
*
|
||||
*
|
||||
* See AUTHORS for copyright information.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* Filename: BolusDTO Description: Bolus DTO
|
||||
*
|
||||
*
|
||||
* Author: Andy {andy@atech-software.com}
|
||||
*/
|
||||
class BolusDTO : PumpTimeStampedRecord() {
|
||||
|
||||
@Expose
|
||||
var requestedAmount: Double? = null
|
||||
|
||||
@Expose
|
||||
var deliveredAmount: Double? = null
|
||||
|
||||
@Expose
|
||||
var immediateAmount: Double? = null // when Multiwave this is used
|
||||
|
||||
@Expose
|
||||
var duration: Int? = null
|
||||
|
||||
@Expose
|
||||
var bolusType: PumpBolusType? = null
|
||||
|
||||
var insulinOnBoard: Double? = null
|
||||
|
||||
private val durationString: String
|
||||
get() {
|
||||
var minutes = duration!!
|
||||
val h = minutes / 60
|
||||
minutes -= h * 60
|
||||
return StringUtil.getLeadingZero(h, 2) + ":" + StringUtil.getLeadingZero(minutes, 2)
|
||||
}
|
||||
|
||||
val value: String?
|
||||
get() = if (bolusType === PumpBolusType.Normal || bolusType === PumpBolusType.Audio) {
|
||||
getFormattedDecimal(deliveredAmount!!)
|
||||
} else if (bolusType === PumpBolusType.Extended) {
|
||||
String.format("AMOUNT_SQUARE=%s;DURATION=%s", getFormattedDecimal(deliveredAmount!!),
|
||||
durationString)
|
||||
} else {
|
||||
String.format("AMOUNT=%s;AMOUNT_SQUARE=%s;DURATION=%s", getFormattedDecimal(immediateAmount!!),
|
||||
getFormattedDecimal(deliveredAmount!!), durationString)
|
||||
}
|
||||
|
||||
val displayableValue: String
|
||||
get() {
|
||||
var value = value
|
||||
value = value!!.replace("AMOUNT_SQUARE=", "Amount Square: ")
|
||||
value = value.replace("AMOUNT=", "Amount: ")
|
||||
value = value.replace("DURATION=", "Duration: ")
|
||||
return value
|
||||
}
|
||||
|
||||
override fun getFormattedDecimal(value: Double): String? {
|
||||
return StringUtil.getFormatedValueUS(value, 2)
|
||||
}
|
||||
|
||||
val bolusKey: String
|
||||
get() = "Bolus_" + bolusType!!.name
|
||||
|
||||
override fun toString(): String {
|
||||
return "BolusDTO [type=" + bolusType!!.name + ", " + value + "]"
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 18.05.15.
|
||||
*/
|
||||
public class BolusWizardDTO extends PumpTimeStampedRecord {
|
||||
|
||||
// bloodGlucose and bgTarets are in mg/dL
|
||||
public Integer bloodGlucose = 0; // mg/dL
|
||||
public Integer carbs = 0;
|
||||
public String chUnit = "g";
|
||||
|
||||
public Float carbRatio = 0.0f;
|
||||
public Float insulinSensitivity = 0.0f;
|
||||
public Integer bgTargetLow = 0;
|
||||
public Integer bgTargetHigh = 0;
|
||||
public Float bolusTotal = 0.0f;
|
||||
public Float correctionEstimate = 0.0f;
|
||||
public Float foodEstimate = 0.0f;
|
||||
public Float unabsorbedInsulin = 0.0f;
|
||||
|
||||
|
||||
// public LocalDateTime localDateTime;
|
||||
// public long atechDateTime;
|
||||
|
||||
public String getValue() {
|
||||
return String.format(Locale.ENGLISH, "BG=%d;CH=%d;CH_UNIT=%s;CH_INS_RATIO=%5.3f;BG_INS_RATIO=%5.3f;"
|
||||
+ "BG_TARGET_LOW=%d;BG_TARGET_HIGH=%d;BOLUS_TOTAL=%5.3f;"
|
||||
+ "BOLUS_CORRECTION=%5.3f;BOLUS_FOOD=%5.3f;UNABSORBED_INSULIN=%5.3f", //
|
||||
bloodGlucose, carbs, chUnit, carbRatio, insulinSensitivity, bgTargetLow, //
|
||||
bgTargetHigh, bolusTotal, correctionEstimate, foodEstimate, unabsorbedInsulin);
|
||||
}
|
||||
|
||||
public String getDisplayableValue() {
|
||||
return String.format(Locale.ENGLISH, "Bg=%d, CH=%d %s, Ch/Ins Ratio=%5.3f, Bg/Ins Ratio=%5.3f;"
|
||||
+ "Bg Target(L/H)=%d/%d, Bolus: Total=%5.3f, "
|
||||
+ "Correction=%5.3f, Food=%5.3f, IOB=%5.3f", //
|
||||
bloodGlucose, carbs, chUnit, carbRatio, insulinSensitivity, bgTargetLow, //
|
||||
bgTargetHigh, bolusTotal, correctionEstimate, foodEstimate, unabsorbedInsulin);
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return "BolusWizardDTO [dateTime=" + DateTimeUtil.toString(atechDateTime) + ", " + getValue() + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by andy on 18.05.15.
|
||||
*/
|
||||
class BolusWizardDTO : PumpTimeStampedRecord() {
|
||||
|
||||
// bloodGlucose and bgTarets are in mg/dL
|
||||
var bloodGlucose = 0 // mg/dL
|
||||
var carbs = 0
|
||||
var chUnit = "g"
|
||||
var carbRatio = 0.0f
|
||||
var insulinSensitivity = 0.0f
|
||||
var bgTargetLow = 0
|
||||
var bgTargetHigh = 0
|
||||
var bolusTotal = 0.0f
|
||||
var correctionEstimate = 0.0f
|
||||
var foodEstimate = 0.0f
|
||||
var unabsorbedInsulin = 0.0f//
|
||||
|
||||
|
||||
val value: String
|
||||
get() = String.format(Locale.ENGLISH, "BG=%d;CH=%d;CH_UNIT=%s;CH_INS_RATIO=%5.3f;BG_INS_RATIO=%5.3f;"
|
||||
+ "BG_TARGET_LOW=%d;BG_TARGET_HIGH=%d;BOLUS_TOTAL=%5.3f;"
|
||||
+ "BOLUS_CORRECTION=%5.3f;BOLUS_FOOD=%5.3f;UNABSORBED_INSULIN=%5.3f", //
|
||||
bloodGlucose, carbs, chUnit, carbRatio, insulinSensitivity, bgTargetLow, //
|
||||
bgTargetHigh, bolusTotal, correctionEstimate, foodEstimate, unabsorbedInsulin)
|
||||
|
||||
//
|
||||
//
|
||||
val displayableValue: String
|
||||
get() = String.format(Locale.ENGLISH, "Bg=%d, CH=%d %s, Ch/Ins Ratio=%5.3f, Bg/Ins Ratio=%5.3f;"
|
||||
+ "Bg Target(L/H)=%d/%d, Bolus: Total=%5.3f, "
|
||||
+ "Correction=%5.3f, Food=%5.3f, IOB=%5.3f", //
|
||||
bloodGlucose, carbs, chUnit, carbRatio, insulinSensitivity, bgTargetLow, //
|
||||
bgTargetHigh, bolusTotal, correctionEstimate, foodEstimate, unabsorbedInsulin)
|
||||
|
||||
override fun toString(): String {
|
||||
return "BolusWizardDTO [dateTime=" + DateTimeUtil.toString(atechDateTime) + ", " + value + "]"
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Created by andy on 2/27/19.
|
||||
*/
|
||||
|
||||
public class ClockDTO {
|
||||
|
||||
public LocalDateTime localDeviceTime;
|
||||
|
||||
public LocalDateTime pumpTime;
|
||||
|
||||
public int timeDifference; // s (pump -> local)
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto
|
||||
|
||||
import org.joda.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Created by andy on 2/27/19.
|
||||
*/
|
||||
class ClockDTO {
|
||||
var localDeviceTime: LocalDateTime? = null
|
||||
var pumpTime: LocalDateTime? = null
|
||||
var timeDifference = 0
|
||||
}
|
|
@ -1,255 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import info.nightscout.androidaps.db.TDD;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
|
||||
|
||||
/**
|
||||
* Created by andy on 11/3/18.
|
||||
*/
|
||||
|
||||
/**
|
||||
* NOTE: Decoding is only done for insulin part, everything else is pretty must left undecoded.
|
||||
*/
|
||||
|
||||
public class DailyTotalsDTO {
|
||||
|
||||
// bg avg, bg low hi, number Bgs,
|
||||
// Sen Avg, Sen Lo/Hi, Sens Cal/Data = 0/0,
|
||||
// Insulin=19.8[8,9], Basal[10,11], Bolus[13,14], Carbs,
|
||||
// Bolus=1.7, Fodd, Corr, Manual=1.7,
|
||||
// Num bOlus=1, food/corr, Food+corr, manual bolus=1
|
||||
private Double bgAvg;
|
||||
private Double bgLow;
|
||||
private Double bgHigh;
|
||||
private Integer bgCount;
|
||||
|
||||
private Double sensorAvg;
|
||||
private Double sensorMin;
|
||||
private Double sensorMax;
|
||||
private Integer sensorCalcCount;
|
||||
private Integer sensorDataCount;
|
||||
|
||||
@Expose
|
||||
private Double insulinTotal = 0.0d;
|
||||
@Expose
|
||||
private Double insulinBasal = 0.0d;
|
||||
@Expose
|
||||
private Double insulinBolus = 0.0d;
|
||||
private Double insulinCarbs;
|
||||
|
||||
private Double bolusTotal;
|
||||
private Double bolusFood;
|
||||
private Double bolusFoodAndCorr;
|
||||
private Double bolusCorrection;
|
||||
private Double bolusManual;
|
||||
|
||||
private Integer bolusCount;
|
||||
private Integer bolusCountFoodOrCorr;
|
||||
// Integer bolusCountCorr;
|
||||
Integer bolusCountFoodAndCorr;
|
||||
Integer bolusCountManual;
|
||||
private Integer bolusCountFood;
|
||||
private Integer bolusCountCorr;
|
||||
|
||||
PumpHistoryEntry entry;
|
||||
|
||||
|
||||
public DailyTotalsDTO(PumpHistoryEntry entry) {
|
||||
this.entry = entry;
|
||||
|
||||
switch (entry.getEntryType()) {
|
||||
case EndResultTotals:
|
||||
decodeEndResultsTotals(entry);
|
||||
break;
|
||||
|
||||
case DailyTotals515:
|
||||
decodeDailyTotals515(entry.getBody());
|
||||
break;
|
||||
|
||||
case DailyTotals522:
|
||||
decodeDailyTotals522(entry.getBody());
|
||||
break;
|
||||
|
||||
case DailyTotals523:
|
||||
decodeDailyTotals523(entry.getBody());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
setDisplayable();
|
||||
}
|
||||
|
||||
|
||||
private void setDisplayable() {
|
||||
|
||||
if (this.insulinBasal == null) {
|
||||
this.entry.setDisplayableValue("Total Insulin: " + StringUtil.getFormatedValueUS(this.insulinTotal, 2));
|
||||
} else {
|
||||
this.entry.setDisplayableValue("Basal Insulin: " + StringUtil.getFormatedValueUS(this.insulinBasal, 2)
|
||||
+ ", Total Insulin: " + StringUtil.getFormatedValueUS(this.insulinTotal, 2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void decodeEndResultsTotals(PumpHistoryEntry entry) {
|
||||
double totals = ByteUtil.toInt((int) entry.getHead()[0], (int) entry.getHead()[1], (int) entry.getHead()[2],
|
||||
(int) entry.getHead()[3], ByteUtil.BitConversion.BIG_ENDIAN) * 0.025d;
|
||||
|
||||
this.insulinTotal = totals;
|
||||
|
||||
entry.addDecodedData("Totals", totals);
|
||||
}
|
||||
|
||||
|
||||
private void testDecode(byte[] data) {
|
||||
|
||||
// Daily
|
||||
|
||||
byte[] body = data; // entry.getBody();
|
||||
//System.out.println("Totals 522");
|
||||
|
||||
for (int i = 0; i < body.length - 2; i++) {
|
||||
|
||||
int j = ByteUtil.toInt(body[i], body[i + 1]);
|
||||
int k = ByteUtil.toInt(body[i], body[i + 1], body[i + 2]);
|
||||
|
||||
int j1 = ByteUtil.toInt(body[i + 1], body[i]);
|
||||
int k1 = ByteUtil.toInt(body[i + 2], body[i + 1], body[i]);
|
||||
|
||||
System.out.println(String.format(Locale.ENGLISH,
|
||||
"index: %d, number=%d, del/40=%.3f, del/10=%.3f, singular=%d, sing_hex=%s", i, j, j / 40.0d, j / 10.0d,
|
||||
body[i], ByteUtil.shortHexString(body[i])));
|
||||
|
||||
System.out.println(String.format(Locale.ENGLISH, " number[k,j1,k1]=%d / %d /%d, del/40=%.3f, del/40=%.3f, del/40=%.3f",
|
||||
k, j1, k1, k / 40.0d, j1 / 40.0d, k1 / 40.0d));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void decodeDailyTotals515(byte[] data) {
|
||||
// LOG.debug("Can't decode DailyTotals515: Body={}", ByteUtil.getHex(data));
|
||||
|
||||
this.insulinTotal = ByteUtil.toInt(data[8], data[9]) / 40.0d;
|
||||
this.insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0d;
|
||||
this.insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0d;
|
||||
|
||||
// Delivery Stats: BG AVG: Bg Low/Hi=none,Number BGs=0
|
||||
// Delivery Stats: INSULIN: Basal 22.30, Bolus=4.20, Catbs = 0g (26.5)
|
||||
// Delivery Stats: BOLUS: Food=0.00, Corr=0.00, Manual=4.20
|
||||
// Delivery Stats: NUM BOLUS: Food/Corr=0,Food+Corr=0, Manual=3
|
||||
|
||||
//LOG.debug("515: {}", toString());
|
||||
}
|
||||
|
||||
|
||||
private void decodeDailyTotals522(byte[] data) {
|
||||
|
||||
this.insulinTotal = ByteUtil.toInt(data[8], data[9]) / 40.0d;
|
||||
this.insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0d;
|
||||
this.insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0d;
|
||||
|
||||
this.bolusTotal = ByteUtil.toInt(data[17], data[18], data[19]) / 40.0d;
|
||||
this.bolusFood = ByteUtil.toInt(data[21], data[22]) / 40.0d;
|
||||
this.bolusCorrection = ByteUtil.toInt(data[23], data[24], data[25]) / 40.0d;
|
||||
this.bolusManual = ByteUtil.toInt(data[26], data[27], data[28]) / 40.0d;
|
||||
|
||||
bolusCount = ByteUtil.asUINT8(data[30]);
|
||||
bolusCountFoodOrCorr = ByteUtil.asUINT8(data[31]);
|
||||
bolusCountFoodAndCorr = ByteUtil.asUINT8(data[32]);
|
||||
bolusCountManual = ByteUtil.asUINT8(data[33]);
|
||||
|
||||
// bg avg, bg low hi, number Bgs,
|
||||
// Sen Avg, Sen Lo/Hi, Sens Cal/Data = 0/0,
|
||||
// Insulin=19.8[8,9], Basal[10,11], Bolus[13,14], Carbs,
|
||||
// Bolus=1.7[18,19], Fodd, Corr, Manual=1.7[27,28],
|
||||
// Num bOlus=1, food/corr, Food+corr, manual bolus=1
|
||||
|
||||
//LOG.debug("522: {}", toString());
|
||||
}
|
||||
|
||||
|
||||
private void decodeDailyTotals523(byte[] data) {
|
||||
|
||||
this.insulinTotal = ByteUtil.toInt(data[8], data[9]) / 40.0d;
|
||||
this.insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0d;
|
||||
this.insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0d;
|
||||
this.insulinCarbs = ByteUtil.toInt(data[16], data[17]) * 1.0d;
|
||||
|
||||
this.bolusFood = ByteUtil.toInt(data[18], data[19]) / 40.0d;
|
||||
this.bolusCorrection = ByteUtil.toInt(data[20], data[21]) / 40.0d;
|
||||
this.bolusFoodAndCorr = ByteUtil.toInt(data[22], data[23]) / 40.0d;
|
||||
this.bolusManual = ByteUtil.toInt(data[24], data[25]) / 40.0d;
|
||||
|
||||
this.bolusCountFood = ByteUtil.asUINT8(data[26]);
|
||||
this.bolusCountCorr = ByteUtil.asUINT8(data[27]);
|
||||
this.bolusCountFoodAndCorr = ByteUtil.asUINT8(data[28]);
|
||||
this.bolusCountManual = ByteUtil.asUINT8(data[29]); // +
|
||||
|
||||
// Delivery Stats: Carbs=11, Total Insulin=3.850, Basal=2.000
|
||||
// Delivery Stats: Basal 52,Bolus 1.850, Bolus=48%o
|
||||
// Delivery Stats: Food only=0.9, Food only#=1, Corr only = 0.0
|
||||
// Delivery Stats: #Corr_only=0,Food+Corr=0.000, #Food+Corr=0
|
||||
// Delivery Stats: Manual = 0.95, #Manual=5
|
||||
|
||||
//LOG.debug("523: {}", toString());
|
||||
}
|
||||
|
||||
@Override @NonNull
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this)
|
||||
.append("bgAvg", bgAvg)
|
||||
.append("bgLow", bgLow)
|
||||
.append("bgHigh", bgHigh)
|
||||
.append("bgCount", bgCount)
|
||||
.append("sensorAvg", sensorAvg)
|
||||
.append("sensorMin", sensorMin)
|
||||
.append("sensorMax", sensorMax)
|
||||
.append("sensorCalcCount", sensorCalcCount)
|
||||
.append("sensorDataCount", sensorDataCount)
|
||||
.append("insulinTotal", insulinTotal)
|
||||
.append("insulinBasal", insulinBasal)
|
||||
.append("insulinBolus", insulinBolus)
|
||||
.append("insulinCarbs", insulinCarbs)
|
||||
.append("bolusTotal", bolusTotal)
|
||||
.append("bolusFood", bolusFood)
|
||||
.append("bolusFoodAndCorr", bolusFoodAndCorr)
|
||||
.append("bolusCorrection", bolusCorrection)
|
||||
.append("bolusManual", bolusManual)
|
||||
.append("bolusCount", bolusCount)
|
||||
.append("bolusCountFoodOrCorr", bolusCountFoodOrCorr)
|
||||
.append("bolusCountFoodAndCorr", bolusCountFoodAndCorr)
|
||||
.append("bolusCountManual", bolusCountManual)
|
||||
.append("bolusCountFood", bolusCountFood)
|
||||
.append("bolusCountCorr", bolusCountCorr)
|
||||
.append("entry", entry)
|
||||
.toString();
|
||||
}
|
||||
|
||||
public void setTDD(TDD tdd) {
|
||||
tdd.date = DateTimeUtil.toMillisFromATD(this.entry.getAtechDateTime());
|
||||
tdd.basal = insulinBasal;
|
||||
tdd.bolus = insulinBolus;
|
||||
tdd.total = insulinTotal;
|
||||
}
|
||||
|
||||
|
||||
public boolean doesEqual(TDD tdd) {
|
||||
return tdd.total == this.insulinTotal && tdd.bolus == this.insulinBolus && tdd.basal == this.insulinBasal;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto
|
||||
|
||||
import com.google.gson.annotations.Expose
|
||||
import info.nightscout.androidaps.db.TDD
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntryType
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by andy on 11/3/18.
|
||||
*/
|
||||
/**
|
||||
* NOTE: Decoding is only done for insulin part, everything else is pretty must left undecoded.
|
||||
*/
|
||||
class DailyTotalsDTO(var entry: PumpHistoryEntry) {
|
||||
|
||||
// bg avg, bg low hi, number Bgs,
|
||||
// Sen Avg, Sen Lo/Hi, Sens Cal/Data = 0/0,
|
||||
// Insulin=19.8[8,9], Basal[10,11], Bolus[13,14], Carbs,
|
||||
// Bolus=1.7, Fodd, Corr, Manual=1.7,
|
||||
// Num bOlus=1, food/corr, Food+corr, manual bolus=1
|
||||
private val bgAvg: Double? = null
|
||||
private val bgLow: Double? = null
|
||||
private val bgHigh: Double? = null
|
||||
private val bgCount: Int? = null
|
||||
private val sensorAvg: Double? = null
|
||||
private val sensorMin: Double? = null
|
||||
private val sensorMax: Double? = null
|
||||
private val sensorCalcCount: Int? = null
|
||||
private val sensorDataCount: Int? = null
|
||||
|
||||
@Expose
|
||||
private var insulinTotal = 0.0
|
||||
|
||||
@Expose
|
||||
private var insulinBasal: Double? = 0.0
|
||||
|
||||
@Expose
|
||||
private var insulinBolus = 0.0
|
||||
private var insulinCarbs: Double? = null
|
||||
private var bolusTotal: Double? = null
|
||||
private var bolusFood: Double? = null
|
||||
private var bolusFoodAndCorr: Double? = null
|
||||
private var bolusCorrection: Double? = null
|
||||
private var bolusManual: Double? = null
|
||||
private var bolusCount: Int? = null
|
||||
private var bolusCountFoodOrCorr: Int? = null
|
||||
|
||||
// Integer bolusCountCorr;
|
||||
var bolusCountFoodAndCorr: Int? = null
|
||||
var bolusCountManual: Int? = null
|
||||
private var bolusCountFood: Int? = null
|
||||
private var bolusCountCorr: Int? = null
|
||||
private fun setDisplayable() {
|
||||
if (insulinBasal == null) {
|
||||
entry.displayableValue = "Total Insulin: " + StringUtil.getFormatedValueUS(insulinTotal, 2)
|
||||
} else {
|
||||
entry.displayableValue = ("Basal Insulin: " + StringUtil.getFormatedValueUS(insulinBasal, 2)
|
||||
+ ", Total Insulin: " + StringUtil.getFormatedValueUS(insulinTotal, 2))
|
||||
}
|
||||
}
|
||||
|
||||
private fun decodeEndResultsTotals(entry: PumpHistoryEntry) {
|
||||
val totals = ByteUtil.toInt(entry.head!![0].toInt(), entry.head!![1].toInt(), entry.head!![2].toInt(),
|
||||
entry.head!![3].toInt(), ByteUtil.BitConversion.BIG_ENDIAN) * 0.025
|
||||
insulinTotal = totals
|
||||
entry.addDecodedData("Totals", totals)
|
||||
}
|
||||
|
||||
private fun testDecode(data: ByteArray) {
|
||||
|
||||
// Daily
|
||||
//System.out.println("Totals 522");
|
||||
for (i in 0 until data.size - 2) {
|
||||
val j = ByteUtil.toInt(data[i], data[i + 1])
|
||||
val k: Int = ByteUtil.toInt(data[i], data[i + 1], data[i + 2])
|
||||
val j1 = ByteUtil.toInt(data[i + 1], data[i])
|
||||
val k1: Int = ByteUtil.toInt(data[i + 2], data[i + 1], data[i])
|
||||
println(String.format(Locale.ENGLISH,
|
||||
"index: %d, number=%d, del/40=%.3f, del/10=%.3f, singular=%d, sing_hex=%s", i, j, j / 40.0, j / 10.0,
|
||||
data[i], ByteUtil.shortHexString(data[i])))
|
||||
println(String.format(Locale.ENGLISH, " number[k,j1,k1]=%d / %d /%d, del/40=%.3f, del/40=%.3f, del/40=%.3f",
|
||||
k, j1, k1, k / 40.0, j1 / 40.0, k1 / 40.0))
|
||||
}
|
||||
}
|
||||
|
||||
private fun decodeDailyTotals515(data: ByteArray?) {
|
||||
// LOG.debug("Can't decode DailyTotals515: Body={}", ByteUtil.getHex(data));
|
||||
insulinTotal = ByteUtil.toInt(data!![8], data[9]) / 40.0
|
||||
insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0
|
||||
insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0
|
||||
|
||||
// Delivery Stats: BG AVG: Bg Low/Hi=none,Number BGs=0
|
||||
// Delivery Stats: INSULIN: Basal 22.30, Bolus=4.20, Catbs = 0g (26.5)
|
||||
// Delivery Stats: BOLUS: Food=0.00, Corr=0.00, Manual=4.20
|
||||
// Delivery Stats: NUM BOLUS: Food/Corr=0,Food+Corr=0, Manual=3
|
||||
|
||||
//LOG.debug("515: {}", toString());
|
||||
}
|
||||
|
||||
private fun decodeDailyTotals522(data: ByteArray?) {
|
||||
insulinTotal = ByteUtil.toInt(data!![8], data[9]) / 40.0
|
||||
insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0
|
||||
insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0
|
||||
bolusTotal = ByteUtil.toInt(data[17], data[18], data[19]) / 40.0
|
||||
bolusFood = ByteUtil.toInt(data[21], data[22]) / 40.0
|
||||
bolusCorrection = ByteUtil.toInt(data[23], data[24], data[25]) / 40.0
|
||||
bolusManual = ByteUtil.toInt(data[26], data[27], data[28]) / 40.0
|
||||
bolusCount = ByteUtil.asUINT8(data[30])
|
||||
bolusCountFoodOrCorr = ByteUtil.asUINT8(data[31])
|
||||
bolusCountFoodAndCorr = ByteUtil.asUINT8(data[32])
|
||||
bolusCountManual = ByteUtil.asUINT8(data[33])
|
||||
|
||||
// bg avg, bg low hi, number Bgs,
|
||||
// Sen Avg, Sen Lo/Hi, Sens Cal/Data = 0/0,
|
||||
// Insulin=19.8[8,9], Basal[10,11], Bolus[13,14], Carbs,
|
||||
// Bolus=1.7[18,19], Fodd, Corr, Manual=1.7[27,28],
|
||||
// Num bOlus=1, food/corr, Food+corr, manual bolus=1
|
||||
|
||||
//LOG.debug("522: {}", toString());
|
||||
}
|
||||
|
||||
private fun decodeDailyTotals523(data: ByteArray?) {
|
||||
insulinTotal = ByteUtil.toInt(data!![8], data[9]) / 40.0
|
||||
insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0
|
||||
insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0
|
||||
insulinCarbs = ByteUtil.toInt(data[16], data[17]) * 1.0
|
||||
bolusFood = ByteUtil.toInt(data[18], data[19]) / 40.0
|
||||
bolusCorrection = ByteUtil.toInt(data[20], data[21]) / 40.0
|
||||
bolusFoodAndCorr = ByteUtil.toInt(data[22], data[23]) / 40.0
|
||||
bolusManual = ByteUtil.toInt(data[24], data[25]) / 40.0
|
||||
bolusCountFood = ByteUtil.asUINT8(data[26])
|
||||
bolusCountCorr = ByteUtil.asUINT8(data[27])
|
||||
bolusCountFoodAndCorr = ByteUtil.asUINT8(data[28])
|
||||
bolusCountManual = ByteUtil.asUINT8(data[29]) // +
|
||||
|
||||
// Delivery Stats: Carbs=11, Total Insulin=3.850, Basal=2.000
|
||||
// Delivery Stats: Basal 52,Bolus 1.850, Bolus=48%o
|
||||
// Delivery Stats: Food only=0.9, Food only#=1, Corr only = 0.0
|
||||
// Delivery Stats: #Corr_only=0,Food+Corr=0.000, #Food+Corr=0
|
||||
// Delivery Stats: Manual = 0.95, #Manual=5
|
||||
|
||||
//LOG.debug("523: {}", toString());
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return ToStringBuilder(this)
|
||||
.append("bgAvg", bgAvg)
|
||||
.append("bgLow", bgLow)
|
||||
.append("bgHigh", bgHigh)
|
||||
.append("bgCount", bgCount)
|
||||
.append("sensorAvg", sensorAvg)
|
||||
.append("sensorMin", sensorMin)
|
||||
.append("sensorMax", sensorMax)
|
||||
.append("sensorCalcCount", sensorCalcCount)
|
||||
.append("sensorDataCount", sensorDataCount)
|
||||
.append("insulinTotal", insulinTotal)
|
||||
.append("insulinBasal", insulinBasal)
|
||||
.append("insulinBolus", insulinBolus)
|
||||
.append("insulinCarbs", insulinCarbs)
|
||||
.append("bolusTotal", bolusTotal)
|
||||
.append("bolusFood", bolusFood)
|
||||
.append("bolusFoodAndCorr", bolusFoodAndCorr)
|
||||
.append("bolusCorrection", bolusCorrection)
|
||||
.append("bolusManual", bolusManual)
|
||||
.append("bolusCount", bolusCount)
|
||||
.append("bolusCountFoodOrCorr", bolusCountFoodOrCorr)
|
||||
.append("bolusCountFoodAndCorr", bolusCountFoodAndCorr)
|
||||
.append("bolusCountManual", bolusCountManual)
|
||||
.append("bolusCountFood", bolusCountFood)
|
||||
.append("bolusCountCorr", bolusCountCorr)
|
||||
.append("entry", entry)
|
||||
.toString()
|
||||
}
|
||||
|
||||
fun setTDD(tdd: TDD) {
|
||||
tdd.date = DateTimeUtil.toMillisFromATD(entry.atechDateTime!!)
|
||||
tdd.basal = insulinBasal!!
|
||||
tdd.bolus = insulinBolus
|
||||
tdd.total = insulinTotal
|
||||
}
|
||||
|
||||
fun doesEqual(tdd: TDD): Boolean {
|
||||
return tdd.total == insulinTotal && tdd.bolus == insulinBolus && tdd.basal == insulinBasal
|
||||
}
|
||||
|
||||
init {
|
||||
when (entry.entryType) {
|
||||
PumpHistoryEntryType.EndResultTotals -> decodeEndResultsTotals(entry)
|
||||
PumpHistoryEntryType.DailyTotals515 -> decodeDailyTotals515(entry.body)
|
||||
PumpHistoryEntryType.DailyTotals522 -> decodeDailyTotals522(entry.body)
|
||||
PumpHistoryEntryType.DailyTotals523 -> decodeDailyTotals523(entry.body)
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
setDisplayable()
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpConfigurationGroup;
|
||||
|
||||
/**
|
||||
* Created by andy on 6/6/18.
|
||||
*/
|
||||
|
||||
public class PumpSettingDTO {
|
||||
|
||||
public String key;
|
||||
public String value;
|
||||
|
||||
PumpConfigurationGroup configurationGroup;
|
||||
|
||||
|
||||
public PumpSettingDTO(String key, String value, PumpConfigurationGroup configurationGroup) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.configurationGroup = configurationGroup;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PumpSettingDTO [key=" + key + ",value=" + value + ",group=" + configurationGroup.name() + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpConfigurationGroup
|
||||
|
||||
/**
|
||||
* Created by andy on 6/6/18.
|
||||
*/
|
||||
class PumpSettingDTO(var key: String, var value: String, var configurationGroup: PumpConfigurationGroup) {
|
||||
|
||||
override fun toString(): String {
|
||||
return "PumpSettingDTO [key=" + key + ",value=" + value + ",group=" + configurationGroup.name + "]"
|
||||
}
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 6/2/18.
|
||||
*/
|
||||
public class PumpTimeStampedRecord {
|
||||
|
||||
protected int decimalPrecission = 2;
|
||||
public long atechDateTime;
|
||||
|
||||
|
||||
public long getAtechDateTime() {
|
||||
return this.atechDateTime;
|
||||
}
|
||||
|
||||
|
||||
public void setAtechDateTime(long atechDateTime) {
|
||||
this.atechDateTime = atechDateTime;
|
||||
}
|
||||
|
||||
|
||||
public String getFormattedDecimal(double value) {
|
||||
return StringUtil.getFormatedValueUS(value, this.decimalPrecission);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil
|
||||
|
||||
/**
|
||||
* Created by andy on 6/2/18.
|
||||
*/
|
||||
open class PumpTimeStampedRecord {
|
||||
|
||||
var decimalPrecission = 2
|
||||
var atechDateTime: Long = 0
|
||||
|
||||
open fun getFormattedDecimal(value: Double): String? {
|
||||
return StringUtil.getFormatedValueUS(value, decimalPrecission)
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
|
||||
public class RLHistoryItemMedtronic extends RLHistoryItem {
|
||||
|
||||
private final MedtronicCommandType medtronicCommandType;
|
||||
|
||||
public RLHistoryItemMedtronic(MedtronicCommandType medtronicCommandType) {
|
||||
super(new LocalDateTime(), RLHistoryItemSource.MedtronicCommand, RileyLinkTargetDevice.MedtronicPump);
|
||||
this.medtronicCommandType = medtronicCommandType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription(ResourceHelper resourceHelper) {
|
||||
if (RLHistoryItemSource.MedtronicCommand.equals(source)) {
|
||||
return medtronicCommandType.name();
|
||||
}
|
||||
|
||||
return super.getDescription(resourceHelper);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import org.joda.time.LocalDateTime
|
||||
|
||||
class RLHistoryItemMedtronic(private val medtronicCommandType: MedtronicCommandType) :
|
||||
RLHistoryItem(LocalDateTime(), RLHistoryItemSource.MedtronicCommand, RileyLinkTargetDevice.MedtronicPump) {
|
||||
|
||||
override fun getDescription(resourceHelper: ResourceHelper): String {
|
||||
return if (RLHistoryItemSource.MedtronicCommand == source) {
|
||||
medtronicCommandType.name
|
||||
} else super.getDescription(resourceHelper)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
|
||||
/**
|
||||
* Created by geoff on 5/29/15.
|
||||
* <p>
|
||||
* Just need a class to keep the pair together, for parcel transport.
|
||||
*/
|
||||
public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.common.defs.TempBasalPair {
|
||||
|
||||
/**
|
||||
* This constructor is for use with PumpHistoryDecoder
|
||||
*
|
||||
* @param rateByte
|
||||
* @param startTimeByte
|
||||
* @param isPercent
|
||||
*/
|
||||
public TempBasalPair(byte rateByte, int startTimeByte, boolean isPercent) {
|
||||
super();
|
||||
int rateInt = ByteUtil.asUINT8(rateByte);
|
||||
|
||||
if (isPercent)
|
||||
this.setInsulinRate(rateByte);
|
||||
else
|
||||
this.setInsulinRate(rateInt * 0.025);
|
||||
this.setDurationMinutes(startTimeByte * 30);
|
||||
this.setPercent(isPercent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This constructor is for use with PumpHistoryDecoder
|
||||
*
|
||||
* @param rateByte0
|
||||
* @param startTimeByte
|
||||
* @param isPercent
|
||||
*/
|
||||
public TempBasalPair(byte rateByte0, byte rateByte1, int startTimeByte, boolean isPercent) {
|
||||
if (isPercent) {
|
||||
this.setInsulinRate(rateByte0);
|
||||
} else {
|
||||
this.setInsulinRate(ByteUtil.toInt(rateByte1, rateByte0) * 0.025);
|
||||
}
|
||||
this.setDurationMinutes(startTimeByte * 30);
|
||||
this.setPercent(isPercent);
|
||||
}
|
||||
|
||||
public TempBasalPair(AAPSLogger aapsLogger, byte[] response) {
|
||||
super();
|
||||
|
||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Received TempBasal response: " + ByteUtil.getHex(response));
|
||||
|
||||
setPercent(response[0] == 1);
|
||||
|
||||
if (isPercent()) {
|
||||
setInsulinRate(response[1]);
|
||||
} else {
|
||||
int strokes = MedtronicUtil.makeUnsignedShort(response[2], response[3]);
|
||||
|
||||
setInsulinRate(strokes / 40.0d);
|
||||
}
|
||||
|
||||
if (response.length < 6) {
|
||||
setDurationMinutes(ByteUtil.asUINT8(response[4]));
|
||||
} else {
|
||||
setDurationMinutes(MedtronicUtil.makeUnsignedShort(response[4], response[5]));
|
||||
}
|
||||
|
||||
aapsLogger.warn(LTag.PUMPBTCOMM, String.format(Locale.ENGLISH, "TempBasalPair (with %d byte response): %s", response.length, toString()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public TempBasalPair(double insulinRate, boolean isPercent, int durationMinutes) {
|
||||
super(insulinRate, isPercent, durationMinutes);
|
||||
}
|
||||
|
||||
|
||||
public byte[] getAsRawData() {
|
||||
|
||||
List<Byte> list = new ArrayList<>();
|
||||
|
||||
list.add((byte) 5);
|
||||
|
||||
byte[] insulinRate = MedtronicUtil.getBasalStrokes(this.getInsulinRate(), true);
|
||||
byte timeMin = (byte) MedtronicUtil.getIntervalFromMinutes(getDurationMinutes());
|
||||
|
||||
// list.add((byte) 0); // ?
|
||||
|
||||
// list.add((byte) 0); // is_absolute
|
||||
|
||||
if (insulinRate.length == 1)
|
||||
list.add((byte) 0x00);
|
||||
else
|
||||
list.add(insulinRate[0]);
|
||||
|
||||
list.add(insulinRate[1]);
|
||||
// list.add((byte) 0); // percent amount
|
||||
|
||||
list.add(timeMin); // 3 (time) - OK
|
||||
|
||||
if (insulinRate.length == 1)
|
||||
list.add((byte) 0x00);
|
||||
else
|
||||
list.add(insulinRate[0]);
|
||||
|
||||
list.add(insulinRate[1]);
|
||||
|
||||
return MedtronicUtil.createByteArray(list);
|
||||
}
|
||||
|
||||
public boolean isCancelTBR() {
|
||||
return (MedtronicUtil.isSame(getInsulinRate(), 0.0d) && getDurationMinutes() == 0);
|
||||
}
|
||||
|
||||
|
||||
public String getDescription() {
|
||||
if (isCancelTBR()) {
|
||||
return "Cancel TBR";
|
||||
}
|
||||
|
||||
if (isPercent()) {
|
||||
return String.format(Locale.ENGLISH, "Rate: %.0f%%, Duration: %d min", getInsulinRate(), getDurationMinutes());
|
||||
} else {
|
||||
return String.format(Locale.ENGLISH, "Rate: %.3f U, Duration: %d min", getInsulinRate(), getDurationMinutes());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NonNull @Override
|
||||
public String toString() {
|
||||
return "TempBasalPair [" + "Rate=" + getInsulinRate() + ", DurationMinutes=" + getDurationMinutes() + ", IsPercent="
|
||||
+ isPercent() + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto
|
||||
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.TempBasalPair
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by geoff on 5/29/15.
|
||||
*
|
||||
* Just need a class to keep the pair together, for parcel transport.
|
||||
*/
|
||||
class TempBasalPair : TempBasalPair {
|
||||
|
||||
/**
|
||||
* This constructor is for use with PumpHistoryDecoder
|
||||
*
|
||||
* @param rateByte
|
||||
* @param startTimeByte
|
||||
* @param isPercent
|
||||
*/
|
||||
constructor(rateByte: Byte, startTimeByte: Int, isPercent: Boolean) : super() {
|
||||
val rateInt = ByteUtil.asUINT8(rateByte)
|
||||
if (isPercent) insulinRate = rateByte.toDouble() else insulinRate = rateInt * 0.025
|
||||
durationMinutes = startTimeByte * 30
|
||||
this.isPercent = isPercent
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor is for use with PumpHistoryDecoder
|
||||
*
|
||||
* @param rateByte0
|
||||
* @param startTimeByte
|
||||
* @param isPercent
|
||||
*/
|
||||
constructor(rateByte0: Byte, rateByte1: Byte, startTimeByte: Int, isPercent: Boolean) {
|
||||
if (isPercent) {
|
||||
insulinRate = rateByte0.toDouble()
|
||||
} else {
|
||||
insulinRate = ByteUtil.toInt(rateByte1.toInt(), rateByte0.toInt()) * 0.025
|
||||
}
|
||||
durationMinutes = startTimeByte * 30
|
||||
this.isPercent = isPercent
|
||||
}
|
||||
|
||||
constructor(aapsLogger: AAPSLogger, response: ByteArray) : super() {
|
||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Received TempBasal response: " + ByteUtil.getHex(response))
|
||||
isPercent = response[0] == 1.toByte()
|
||||
insulinRate = if (isPercent) {
|
||||
response[1].toDouble()
|
||||
} else {
|
||||
val strokes = MedtronicUtil.makeUnsignedShort(response[2].toInt(), response[3].toInt())
|
||||
strokes / 40.0
|
||||
}
|
||||
durationMinutes = if (response.size < 6) {
|
||||
ByteUtil.asUINT8(response[4])
|
||||
} else {
|
||||
MedtronicUtil.makeUnsignedShort(response[4].toInt(), response[5].toInt())
|
||||
}
|
||||
aapsLogger.warn(LTag.PUMPBTCOMM, String.format(Locale.ENGLISH, "TempBasalPair (with %d byte response): %s", response.size, toString()))
|
||||
}
|
||||
|
||||
constructor(insulinRate: Double, isPercent: Boolean, durationMinutes: Int) : super(insulinRate, isPercent, durationMinutes) {}
|
||||
|
||||
// list.add((byte) 0); // ?
|
||||
|
||||
// list.add((byte) 0); // is_absolute
|
||||
// list.add((byte) 0); // percent amount
|
||||
// 3 (time) - OK
|
||||
val asRawData: ByteArray
|
||||
get() {
|
||||
val list: MutableList<Byte> = ArrayList()
|
||||
list.add(5.toByte())
|
||||
val insulinRate = MedtronicUtil.getBasalStrokes(insulinRate, true)
|
||||
val timeMin = MedtronicUtil.getIntervalFromMinutes(durationMinutes).toByte()
|
||||
|
||||
// list.add((byte) 0); // ?
|
||||
|
||||
// list.add((byte) 0); // is_absolute
|
||||
if (insulinRate.size == 1) list.add(0x00.toByte()) else list.add(insulinRate[0])
|
||||
list.add(insulinRate[1])
|
||||
// list.add((byte) 0); // percent amount
|
||||
list.add(timeMin) // 3 (time) - OK
|
||||
if (insulinRate.size == 1) list.add(0x00.toByte()) else list.add(insulinRate[0])
|
||||
list.add(insulinRate[1])
|
||||
return MedtronicUtil.createByteArray(list)
|
||||
}
|
||||
|
||||
val isCancelTBR: Boolean
|
||||
get() = MedtronicUtil.isSame(insulinRate, 0.0) && durationMinutes == 0
|
||||
|
||||
val description: String
|
||||
get() {
|
||||
if (isCancelTBR) {
|
||||
return "Cancel TBR"
|
||||
}
|
||||
return if (isPercent) {
|
||||
String.format(Locale.ENGLISH, "Rate: %.0f%%, Duration: %d min", insulinRate, durationMinutes)
|
||||
} else {
|
||||
String.format(Locale.ENGLISH, "Rate: %.3f U, Duration: %d min", insulinRate, durationMinutes)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return ("TempBasalPair [" + "Rate=" + insulinRate + ", DurationMinutes=" + durationMinutes + ", IsPercent="
|
||||
+ isPercent + "]")
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
|
||||
|
||||
public class TempBasalProcessDTO {
|
||||
|
||||
public PumpHistoryEntry itemOne;
|
||||
public PumpHistoryEntry itemTwo;
|
||||
|
||||
public Operation processOperation = Operation.None;
|
||||
|
||||
public int getDuration() {
|
||||
if (itemTwo == null) {
|
||||
TempBasalPair tbr = (TempBasalPair) itemOne.getDecodedDataEntry("Object");
|
||||
return tbr.getDurationMinutes();
|
||||
} else {
|
||||
int difference = DateTimeUtil.getATechDateDiferenceAsMinutes(itemOne.getAtechDateTime(), itemTwo.getAtechDateTime());
|
||||
return difference;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum Operation {
|
||||
None,
|
||||
Add,
|
||||
Edit
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry
|
||||
|
||||
class TempBasalProcessDTO {
|
||||
@JvmField var itemOne: PumpHistoryEntry? = null
|
||||
@JvmField var itemTwo: PumpHistoryEntry? = null
|
||||
@JvmField var processOperation = Operation.None
|
||||
val duration: Int
|
||||
get() = if (itemTwo == null) {
|
||||
val tbr = itemOne!!.getDecodedDataEntry("Object") as TempBasalPair?
|
||||
tbr!!.durationMinutes
|
||||
} else {
|
||||
DateTimeUtil.getATechDateDiferenceAsMinutes(itemOne!!.atechDateTime, itemTwo!!.atechDateTime)
|
||||
}
|
||||
|
||||
enum class Operation {
|
||||
None, Add, Edit
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs;
|
||||
|
||||
/**
|
||||
* Created by andy on 1/20/19.
|
||||
*/
|
||||
|
||||
public enum BasalProfileStatus {
|
||||
|
||||
NotInitialized, //
|
||||
ProfileOK, //
|
||||
ProfileChanged, //
|
||||
;
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs
|
||||
|
||||
/**
|
||||
* Created by andy on 1/20/19.
|
||||
*/
|
||||
enum class BasalProfileStatus {
|
||||
|
||||
NotInitialized, //
|
||||
ProfileOK, //
|
||||
ProfileChanged
|
||||
//
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.R;
|
||||
|
||||
|
||||
/**
|
||||
* Created by andy on 6/4/18.
|
||||
*/
|
||||
|
||||
public enum BatteryType {
|
||||
|
||||
None(R.string.key_medtronic_pump_battery_no, 0, 0),
|
||||
Alkaline(R.string.key_medtronic_pump_battery_alkaline, 1.20d, 1.47d), //
|
||||
Lithium(R.string.key_medtronic_pump_battery_lithium, 1.22d, 1.64d), //
|
||||
NiZn(R.string.key_medtronic_pump_battery_nizn, 1.40d, 1.70d), //
|
||||
NiMH(R.string.key_medtronic_pump_battery_nimh, 1.10d, 1.40d) //
|
||||
;
|
||||
|
||||
public final @StringRes int description;
|
||||
public final double lowVoltage;
|
||||
public final double highVoltage;
|
||||
|
||||
|
||||
BatteryType(int resId, double lowVoltage, double highVoltage) {
|
||||
this.description = resId;
|
||||
this.lowVoltage = lowVoltage;
|
||||
this.highVoltage = highVoltage;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.R
|
||||
|
||||
/**
|
||||
* Created by andy on 6/4/18.
|
||||
*/
|
||||
enum class BatteryType(@field:StringRes val description: Int, val lowVoltage: Double, val highVoltage: Double) {
|
||||
|
||||
None(R.string.key_medtronic_pump_battery_no, 0.0, 0.0),
|
||||
Alkaline(R.string.key_medtronic_pump_battery_alkaline, 1.20, 1.47), //
|
||||
Lithium(R.string.key_medtronic_pump_battery_lithium, 1.22, 1.64), //
|
||||
NiZn(R.string.key_medtronic_pump_battery_nizn, 1.40, 1.70), //
|
||||
NiMH(R.string.key_medtronic_pump_battery_nimh, 1.10, 1.40 //
|
||||
);
|
||||
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.CommandValueDefinitionType;
|
||||
|
||||
/**
|
||||
* Created by andy on 4/5/19.
|
||||
*/
|
||||
|
||||
public enum CommandValueDefinitionMDTType implements CommandValueDefinitionType {
|
||||
GetModel, //
|
||||
TuneUp, //
|
||||
GetProfile, //
|
||||
GetTBR, //
|
||||
;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String commandAction() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,393 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.R;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.MessageBody;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.PumpAckMessageBody;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.UnknownMessageBody;
|
||||
|
||||
/**
|
||||
* Taken from GNU Gluco Control diabetes management software (ggc.sourceforge.net)
|
||||
* <p>
|
||||
* Description: Medtronic Commands (Pump and CGMS) for all 512 and later models (just 5xx)
|
||||
* <p>
|
||||
* Link to original/unmodified file:
|
||||
* https://sourceforge.net/p/ggc/code/HEAD/tree/trunk/ggc-plugins/ggc-plugins-base/src/
|
||||
* main/java/ggc/plugin/device/impl/minimed/enums/MinimedCommandType.java
|
||||
* <p>
|
||||
* A lot of stuff has been removed because it is not needed anymore (historical stuff from CareLink
|
||||
* and Carelink USB communication.
|
||||
* <p>
|
||||
* Author: Andy {andy@atech-software.com}
|
||||
*/
|
||||
public enum MedtronicCommandType implements Serializable // , MinimedCommandTypeInterface
|
||||
{
|
||||
InvalidCommand(0, "Invalid Command", null, null), //
|
||||
|
||||
// Pump Responses (9)
|
||||
CommandACK(0x06, "ACK - Acknowledge", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
|
||||
CommandNAK(0x15, "NAK - Not Acknowledged", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// All (8)
|
||||
PushAck(91, "Push ACK", MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(2)), //
|
||||
|
||||
PushEsc(91, "Push Esc", MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(1)), //
|
||||
|
||||
PushButton(0x5b, "Push Button", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), // 91
|
||||
|
||||
RFPowerOn(93, "RF Power On", MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(
|
||||
1, 10)), //
|
||||
|
||||
RFPowerOff(93, "RF Power Off", MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(
|
||||
0, 0)), //
|
||||
|
||||
// SetSuspend(77, "Set Suspend", MinimedTargetType.InitCommand, MedtronicDeviceType.All,
|
||||
// MinimedCommandParameterType.FixedParameters, getByteArray(1)), //
|
||||
|
||||
// CancelSuspend(77, "Cancel Suspend", MinimedTargetType.InitCommand, MedtronicDeviceType.All,
|
||||
// MinimedCommandParameterType.FixedParameters, getByteArray(0)), //
|
||||
|
||||
PumpState(131, "Pump State", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
ReadPumpErrorStatus(117, "Pump Error Status", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// 511 (InitCommand = 2, Config 7, Data = 1(+3)
|
||||
// DetectBolus(75, "Detect Bolus", MedtronicDeviceType.Medtronic_511, MinimedCommandParameterType.FixedParameters, getByteArray(
|
||||
// 0, 0, 0)), //
|
||||
|
||||
// RemoteControlIds(118, "Remote Control Ids", MinimedTargetType.PumpConfiguration_NA, MedtronicDeviceType.All,
|
||||
// MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// FirmwareVersion(116, "Firmware Version", MinimedTargetType.InitCommand, MedtronicDeviceType.All,
|
||||
// MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// PumpId(113, "Pump Id", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.All,
|
||||
// MinimedCommandParameterType.NoParameters), // init
|
||||
|
||||
SetRealTimeClock(0x40, "Set Pump Time", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, //
|
||||
0), //
|
||||
|
||||
GetRealTimeClock(112, "Get Pump Time", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, //
|
||||
7, R.string.medtronic_cmd_desc_get_time), // 0x70
|
||||
|
||||
GetBatteryStatus(0x72, "Get Battery Status", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
|
||||
// GetBattery((byte) 0x72), //
|
||||
|
||||
GetRemainingInsulin(0x73, "Read Remaining Insulin", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, 2), // 115
|
||||
|
||||
SetBolus(0x42, "Set Bolus", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, //
|
||||
0, R.string.medtronic_cmd_desc_set_bolus), // 66
|
||||
|
||||
// 512
|
||||
ReadTemporaryBasal(0x98, "Read Temporary Basal", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
5, R.string.medtronic_cmd_desc_get_tbr), // 152
|
||||
|
||||
SetTemporaryBasal(76, "Set Temporay Basal", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
0, R.string.medtronic_cmd_desc_set_tbr),
|
||||
|
||||
// 512 Config
|
||||
PumpModel(141, "Pump Model", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
5, R.string.medtronic_cmd_desc_get_model), // 0x8D
|
||||
|
||||
// BGTargets_512(140, "BG Targets", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512_712,
|
||||
// MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// BGUnits(137, "BG Units", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher,
|
||||
// MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// Language(134, "Language", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher,
|
||||
// MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
Settings_512(145, "Configuration", MedtronicDeviceType.Medtronic_512_712, MinimedCommandParameterType.NoParameters, //
|
||||
64, 1, 18, R.string.medtronic_cmd_desc_get_settings), //
|
||||
|
||||
// BGAlarmClocks(142, "BG Alarm Clocks", MinimedTargetType.PumpConfiguration,
|
||||
// MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// BGAlarmEnable(151, "BG Alarm Enable", MinimedTargetType.PumpConfiguration,
|
||||
// MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// BGReminderEnable(144, "BG Reminder Enable", MinimedTargetType.PumpConfiguration,
|
||||
// MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// ReadInsulinSensitivities(0x8b, "Read Insulin Sensitivities", MinimedTargetType.PumpConfiguration,
|
||||
// MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), // 139
|
||||
|
||||
// 512 Data
|
||||
GetHistoryData(128, "Get History", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.SubCommands, //
|
||||
1024, 16, 1024, R.string.medtronic_cmd_desc_get_history), // 0x80
|
||||
|
||||
GetBasalProfileSTD(146, "Get Profile Standard", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_get_basal_profile), // 146
|
||||
|
||||
GetBasalProfileA(147, "Get Profile A", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_get_basal_profile),
|
||||
|
||||
GetBasalProfileB(148, "Get Profile B", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_get_basal_profile), // 148
|
||||
|
||||
SetBasalProfileSTD(0x6f, "Set Profile Standard", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_set_basal_profile), // 111
|
||||
|
||||
SetBasalProfileA(0x30, "Set Profile A", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_set_basal_profile), // 48
|
||||
|
||||
SetBasalProfileB(0x31, "Set Profile B", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_set_basal_profile), // 49
|
||||
|
||||
// 515
|
||||
PumpStatus(206, "Pump Status", MedtronicDeviceType.Medtronic_515andHigher, MinimedCommandParameterType.NoParameters), // PumpConfiguration
|
||||
|
||||
Settings(192, "Configuration", MedtronicDeviceType.Medtronic_515andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 1, 21, R.string.medtronic_cmd_desc_get_settings), //
|
||||
|
||||
// 522
|
||||
SensorSettings_522(153, "Sensor Configuration", MedtronicDeviceType.Medtronic_522andHigher, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
GlucoseHistory(154, "Glucose History", MedtronicDeviceType.Medtronic_522andHigher, MinimedCommandParameterType.SubCommands, 1024, 32, 0, null), //
|
||||
|
||||
// 523
|
||||
SensorSettings(207, "Sensor Configuration", MedtronicDeviceType.Medtronic_523andHigher, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// 553
|
||||
// 554
|
||||
|
||||
// var MESSAGES = {
|
||||
// READ_TIME : 0x70,
|
||||
// READ_BATTERY_STATUS: 0x72,
|
||||
// READ_HISTORY : 0x80,
|
||||
// READ_CARB_RATIOS : 0x8A,
|
||||
// READ_INSULIN_SENSITIVITIES: 0x8B,
|
||||
// READ_MODEL : 0x8D,
|
||||
// READ_PROFILE_STD : 0x92,
|
||||
// READ_PROFILE_A : 0x93,
|
||||
// READ_PROFILE_B : 0x94,
|
||||
// READ_CBG_HISTORY: 0x9A,
|
||||
// READ_ISIG_HISTORY: 0x9B,
|
||||
// READ_CURRENT_PAGE : 0x9D,
|
||||
// READ_BG_TARGETS : 0x9F,
|
||||
// READ_SETTINGS : 0xC0, 192
|
||||
// READ_CURRENT_CBG_PAGE : 0xCD
|
||||
// };
|
||||
|
||||
// Fake Commands
|
||||
|
||||
CancelTBR(),
|
||||
;
|
||||
|
||||
static Map<Byte, MedtronicCommandType> mapByCode;
|
||||
|
||||
static {
|
||||
MedtronicCommandType.RFPowerOn.maxAllowedTime = 17000;
|
||||
MedtronicCommandType.RFPowerOn.allowedRetries = 0;
|
||||
MedtronicCommandType.RFPowerOn.recordLength = 0;
|
||||
MedtronicCommandType.RFPowerOn.minimalBufferSizeToStartReading = 1;
|
||||
|
||||
mapByCode = new HashMap<>();
|
||||
|
||||
for (MedtronicCommandType medtronicCommandType : values()) {
|
||||
mapByCode.put(medtronicCommandType.getCommandCode(), medtronicCommandType);
|
||||
}
|
||||
}
|
||||
|
||||
public byte commandCode = 0;
|
||||
public String commandDescription = "";
|
||||
public byte[] commandParameters = null;
|
||||
public int commandParametersCount = 0;
|
||||
public int maxRecords = 1;
|
||||
private Integer resourceId;
|
||||
public int command_type = 0;
|
||||
public int allowedRetries = 2;
|
||||
public int maxAllowedTime = 2000;
|
||||
public MinimedCommandParameterType parameterType;
|
||||
public int minimalBufferSizeToStartReading = 14;
|
||||
public int expectedLength = 0;
|
||||
//MinimedTargetType targetType;
|
||||
MedtronicDeviceType devices;
|
||||
private int recordLength = 64;
|
||||
|
||||
|
||||
MedtronicCommandType() {
|
||||
// this is for "fake" commands needed by AAPS MedtronicUITask
|
||||
}
|
||||
|
||||
|
||||
MedtronicCommandType(int code, String description, MedtronicDeviceType devices,
|
||||
MinimedCommandParameterType parameterType, byte[] cmd_params) {
|
||||
this(code, description, devices, parameterType, 0, 1, 0, 0, 11, 0);
|
||||
|
||||
this.commandParameters = cmd_params;
|
||||
this.commandParametersCount = cmd_params.length;
|
||||
}
|
||||
|
||||
|
||||
MedtronicCommandType(int code, String description, MedtronicDeviceType devices, //
|
||||
MinimedCommandParameterType parameterType) {
|
||||
|
||||
this(code, description, devices, parameterType, 64, 1, 0, null);
|
||||
}
|
||||
|
||||
// NEW
|
||||
MedtronicCommandType(int code, String description, MedtronicDeviceType devices, //
|
||||
MinimedCommandParameterType parameterType, int expectedLength) {
|
||||
this(code, description, devices, parameterType, 64, 1, expectedLength, null);
|
||||
}
|
||||
|
||||
|
||||
// NEW
|
||||
MedtronicCommandType(int code, String description, MedtronicDeviceType devices, //
|
||||
MinimedCommandParameterType parameterType, int expectedLength, int resourceId) {
|
||||
this(code, description, devices, parameterType, 64, 1, expectedLength, resourceId);
|
||||
}
|
||||
|
||||
|
||||
// NEW
|
||||
MedtronicCommandType(int code, String description,
|
||||
MedtronicDeviceType devices, //
|
||||
MinimedCommandParameterType parameterType, int recordLength, int max_recs, int expectedLength,
|
||||
Integer resourceId) {
|
||||
this.commandCode = (byte) code;
|
||||
this.commandDescription = description;
|
||||
this.devices = devices;
|
||||
this.recordLength = recordLength;
|
||||
this.maxRecords = max_recs;
|
||||
this.resourceId = resourceId;
|
||||
|
||||
this.commandParametersCount = 0;
|
||||
this.allowedRetries = 2;
|
||||
this.parameterType = parameterType;
|
||||
this.expectedLength = expectedLength;
|
||||
|
||||
if (this.parameterType == MinimedCommandParameterType.SubCommands) {
|
||||
this.minimalBufferSizeToStartReading = 200;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
MedtronicCommandType(int code, String description, MedtronicDeviceType devices, //
|
||||
MinimedCommandParameterType parameterType, int recordLength, int max_recs, int addy, //
|
||||
int addy_len, int cmd_type, int expectedLength) {
|
||||
this.commandCode = (byte) code;
|
||||
this.commandDescription = description;
|
||||
//this.targetType = targetType;
|
||||
this.devices = devices;
|
||||
this.recordLength = recordLength;
|
||||
this.maxRecords = max_recs;
|
||||
|
||||
this.command_type = cmd_type;
|
||||
this.commandParametersCount = 0;
|
||||
this.allowedRetries = 2;
|
||||
this.parameterType = parameterType;
|
||||
this.expectedLength = expectedLength;
|
||||
|
||||
if (this.parameterType == MinimedCommandParameterType.SubCommands) {
|
||||
this.minimalBufferSizeToStartReading = 200;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static HashMap<MedtronicDeviceType, String> getDeviceTypesArray(MedtronicDeviceType... types) {
|
||||
HashMap<MedtronicDeviceType, String> hashMap = new HashMap<MedtronicDeviceType, String>();
|
||||
|
||||
for (MedtronicDeviceType type : types) {
|
||||
hashMap.put(type, null);
|
||||
}
|
||||
|
||||
return hashMap;
|
||||
}
|
||||
|
||||
|
||||
private static byte[] getByteArray(int... data) {
|
||||
byte[] array = new byte[data.length];
|
||||
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
array[i] = (byte) data[i];
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
private static int[] getIntArray(int... data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public static MedtronicCommandType getByCode(byte code) {
|
||||
if (mapByCode.containsKey(code)) {
|
||||
return mapByCode.get(code);
|
||||
} else {
|
||||
return MedtronicCommandType.InvalidCommand;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static MessageBody constructMessageBody(MedtronicCommandType messageType, byte[] bodyData) {
|
||||
switch (messageType) {
|
||||
case CommandACK:
|
||||
return new PumpAckMessageBody(bodyData);
|
||||
default:
|
||||
return new UnknownMessageBody(bodyData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static MedtronicCommandType getSettings(MedtronicDeviceType medtronicPumpModel) {
|
||||
if (MedtronicDeviceType.isSameDevice(medtronicPumpModel, MedtronicDeviceType.Medtronic_512_712))
|
||||
return MedtronicCommandType.Settings_512;
|
||||
else
|
||||
return MedtronicCommandType.Settings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Full Command Description
|
||||
*
|
||||
* @return command description
|
||||
*/
|
||||
public String getFullCommandDescription() {
|
||||
return "Command [name=" + this.name() + ", id=" + this.commandCode + ",description=" + this.commandDescription
|
||||
+ "] ";
|
||||
}
|
||||
|
||||
|
||||
public byte getCommandCode() {
|
||||
return commandCode;
|
||||
}
|
||||
|
||||
|
||||
public int getCommandParametersCount() {
|
||||
if (this.commandParameters == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return this.commandParameters.length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return name();
|
||||
}
|
||||
|
||||
|
||||
public String getCommandDescription() {
|
||||
return this.commandDescription;
|
||||
}
|
||||
|
||||
|
||||
public Integer getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public enum MinimedCommandParameterType {
|
||||
NoParameters, //
|
||||
FixedParameters, //
|
||||
SubCommands //
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,285 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.R
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.MessageBody
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.PumpAckMessageBody
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.UnknownMessageBody
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType.Companion.isSameDevice
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Taken from GNU Gluco Control diabetes management software (ggc.sourceforge.net)
|
||||
*
|
||||
*
|
||||
* Description: Medtronic Commands (Pump and CGMS) for all 512 and later models (just 5xx)
|
||||
*
|
||||
*
|
||||
* Link to original/unmodified file:
|
||||
* https://sourceforge.net/p/ggc/code/HEAD/tree/trunk/ggc-plugins/ggc-plugins-base/src/
|
||||
* main/java/ggc/plugin/device/impl/minimed/enums/MinimedCommandType.java
|
||||
*
|
||||
*
|
||||
* A lot of stuff has been removed because it is not needed anymore (historical stuff from CareLink
|
||||
* and Carelink USB communication.
|
||||
*
|
||||
*
|
||||
* Author: Andy {andy@atech-software.com}
|
||||
*/
|
||||
enum class MedtronicCommandType
|
||||
{
|
||||
|
||||
InvalidCommand(0, "Invalid Command", null, null), //
|
||||
|
||||
// Pump Responses (9)
|
||||
CommandACK(0x06, "ACK - Acknowledge", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
|
||||
CommandNAK(0x15, "NAK - Not Acknowledged", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// All (8)
|
||||
PushAck(91, "Push ACK", MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, byteArrayOf(2)), //
|
||||
PushEsc(91, "Push Esc", MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, byteArrayOf(1)), //
|
||||
PushButton(0x5b, "Push Button", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), // 91
|
||||
RFPowerOn(93, "RF Power On", MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, byteArrayOf(1, 10)), //
|
||||
RFPowerOff(93, "RF Power Off", MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, byteArrayOf(0, 0)), //
|
||||
|
||||
// SetSuspend(77, "Set Suspend", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(1)), //
|
||||
// CancelSuspend(77, "Cancel Suspend", MinimedTargetType.InitCommand, MedtronicDeviceType.All,MinimedCommandParameterType.FixedParameters, getByteArray(0)), //
|
||||
PumpState(131, "Pump State", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
|
||||
ReadPumpErrorStatus(117, "Pump Error Status", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// 511 (InitCommand = 2, Config 7, Data = 1(+3)
|
||||
// DetectBolus(75, "Detect Bolus", MedtronicDeviceType.Medtronic_511, MinimedCommandParameterType.FixedParameters, getByteArray(
|
||||
// 0, 0, 0)), //
|
||||
// RemoteControlIds(118, "Remote Control Ids", MinimedTargetType.PumpConfiguration_NA, MedtronicDeviceType.All,MinimedCommandParameterType.NoParameters), //
|
||||
// FirmwareVersion(116, "Firmware Version", MinimedTargetType.InitCommand, MedtronicDeviceType.All,MinimedCommandParameterType.NoParameters), //
|
||||
// PumpId(113, "Pump Id", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.All,MinimedCommandParameterType.NoParameters), // init
|
||||
SetRealTimeClock(0x40, "Set Pump Time", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, //
|
||||
0, R.string.medtronic_cmd_desc_set_time), //
|
||||
GetRealTimeClock(112, "Get Pump Time", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, //
|
||||
7, R.string.medtronic_cmd_desc_get_time), // 0x70
|
||||
GetBatteryStatus(0x72, "Get Battery Status", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters,
|
||||
0, R.string.medtronic_cmd_desc_get_battery_status), //
|
||||
GetRemainingInsulin(0x73, "Read Remaining Insulin", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, 2), // 115
|
||||
SetBolus(0x42, "Set Bolus", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, //
|
||||
0, R.string.medtronic_cmd_desc_set_bolus), // 66
|
||||
|
||||
// 512
|
||||
ReadTemporaryBasal(0x98, "Read Temporary Basal", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
5, R.string.medtronic_cmd_desc_get_tbr), // 152
|
||||
SetTemporaryBasal(76, "Set Temporay Basal", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
0, R.string.medtronic_cmd_desc_set_tbr), // 512 Config
|
||||
PumpModel(141, "Pump Model", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
5, R.string.medtronic_cmd_desc_get_model), // 0x8D
|
||||
|
||||
// BGTargets_512(140, "BG Targets", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512_712,
|
||||
// MinimedCommandParameterType.NoParameters), //
|
||||
// BGUnits(137, "BG Units", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher,
|
||||
// MinimedCommandParameterType.NoParameters), //
|
||||
// Language(134, "Language", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher,
|
||||
// MinimedCommandParameterType.NoParameters), //
|
||||
Settings_512(145, "Configuration", MedtronicDeviceType.Medtronic_512_712, MinimedCommandParameterType.NoParameters, //
|
||||
64, 1, 18, R.string.medtronic_cmd_desc_get_settings), //
|
||||
|
||||
// 512 Data
|
||||
GetHistoryData(128, "Get History", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.SubCommands, //
|
||||
1024, 16, 1024, R.string.medtronic_cmd_desc_get_history), // 0x80
|
||||
GetBasalProfileSTD(146, "Get Profile Standard", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_get_basal_profile), // 146
|
||||
GetBasalProfileA(147, "Get Profile A", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_get_basal_profile),
|
||||
GetBasalProfileB(148, "Get Profile B", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_get_basal_profile), // 148
|
||||
SetBasalProfileSTD(0x6f, "Set Profile Standard", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_set_basal_profile), // 111
|
||||
SetBasalProfileA(0x30, "Set Profile A", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_set_basal_profile), // 48
|
||||
SetBasalProfileB(0x31, "Set Profile B", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 3, 192, R.string.medtronic_cmd_desc_set_basal_profile), // 49
|
||||
|
||||
// 515
|
||||
PumpStatus(206, "Pump Status", MedtronicDeviceType.Medtronic_515andHigher, MinimedCommandParameterType.NoParameters), // PumpConfiguration
|
||||
Settings(192, "Configuration", MedtronicDeviceType.Medtronic_515andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 1, 21, R.string.medtronic_cmd_desc_get_settings), //
|
||||
|
||||
// 522
|
||||
SensorSettings_522(153, "Sensor Configuration", MedtronicDeviceType.Medtronic_522andHigher, MinimedCommandParameterType.NoParameters), //
|
||||
GlucoseHistory(154, "Glucose History", MedtronicDeviceType.Medtronic_522andHigher, MinimedCommandParameterType.SubCommands, 1024, 32, 0, null), //
|
||||
|
||||
// 523
|
||||
SensorSettings(207, "Sensor Configuration", MedtronicDeviceType.Medtronic_523andHigher, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
// 553
|
||||
// 554
|
||||
// var MESSAGES = {
|
||||
// READ_TIME : 0x70,
|
||||
// READ_BATTERY_STATUS: 0x72,
|
||||
// READ_HISTORY : 0x80,
|
||||
// READ_CARB_RATIOS : 0x8A,
|
||||
// READ_INSULIN_SENSITIVITIES: 0x8B,
|
||||
// READ_MODEL : 0x8D,
|
||||
// READ_PROFILE_STD : 0x92,
|
||||
// READ_PROFILE_A : 0x93,
|
||||
// READ_PROFILE_B : 0x94,
|
||||
// READ_CBG_HISTORY: 0x9A,
|
||||
// READ_ISIG_HISTORY: 0x9B,
|
||||
// READ_CURRENT_PAGE : 0x9D,
|
||||
// READ_BG_TARGETS : 0x9F,
|
||||
// READ_SETTINGS : 0xC0, 192
|
||||
// READ_CURRENT_CBG_PAGE : 0xCD
|
||||
// };
|
||||
// Fake Commands
|
||||
CancelTBR;
|
||||
|
||||
|
||||
|
||||
companion object {
|
||||
var mapByCode: MutableMap<Byte, MedtronicCommandType> = HashMap()
|
||||
|
||||
private fun getDeviceTypesArray(vararg types: MedtronicDeviceType): HashMap<MedtronicDeviceType, String?> {
|
||||
val hashMap = HashMap<MedtronicDeviceType, String?>()
|
||||
for (type in types) {
|
||||
hashMap[type] = null
|
||||
}
|
||||
return hashMap
|
||||
}
|
||||
|
||||
// @JvmStatic
|
||||
// fun getByteArray(vararg data: Int): ByteArray {
|
||||
// val array = ByteArray(data.size)
|
||||
// for (i in 0 until data.size) {
|
||||
// array[i] = data[i].toByte()
|
||||
// }
|
||||
// return array
|
||||
// }
|
||||
|
||||
// private fun getByteArray(vararg data: Int): ByteArray {
|
||||
// val array = ByteArray(data.size)
|
||||
// for (i in 0 until data.size) {
|
||||
// array[i] = data[i].toByte()
|
||||
// }
|
||||
// return array
|
||||
// }
|
||||
|
||||
private fun getIntArray(vararg data: Int): IntArray {
|
||||
return data
|
||||
}
|
||||
|
||||
fun getByCode(code: Byte): MedtronicCommandType? {
|
||||
return if (mapByCode.containsKey(code)) {
|
||||
mapByCode[code]
|
||||
} else {
|
||||
InvalidCommand
|
||||
}
|
||||
}
|
||||
|
||||
fun constructMessageBody(messageType: MedtronicCommandType?, bodyData: ByteArray?): MessageBody {
|
||||
return when (messageType) {
|
||||
CommandACK -> PumpAckMessageBody(bodyData)
|
||||
else -> UnknownMessageBody(bodyData!!)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getSettings(medtronicPumpModel: MedtronicDeviceType?): MedtronicCommandType {
|
||||
return if (isSameDevice(medtronicPumpModel!!, MedtronicDeviceType.Medtronic_512_712)) Settings_512 else Settings
|
||||
}
|
||||
|
||||
init {
|
||||
RFPowerOn.maxAllowedTime = 17000
|
||||
RFPowerOn.allowedRetries = 0
|
||||
RFPowerOn.recordLength = 0
|
||||
RFPowerOn.minimalBufferSizeToStartReading = 1
|
||||
for (medtronicCommandType in values()) {
|
||||
mapByCode[medtronicCommandType.commandCode] = medtronicCommandType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var commandCode: Byte = 0
|
||||
var commandDescription = ""
|
||||
var commandParameters: ByteArray? = null
|
||||
var commandParametersCount = 0
|
||||
var maxRecords = 1
|
||||
var resourceId: Int? = null
|
||||
private set
|
||||
var command_type = 0
|
||||
var allowedRetries = 2
|
||||
var maxAllowedTime = 2000
|
||||
var parameterType: MinimedCommandParameterType? = null
|
||||
var minimalBufferSizeToStartReading = 14
|
||||
var expectedLength = 0
|
||||
var devices: MedtronicDeviceType? = null
|
||||
private var recordLength = 64
|
||||
|
||||
constructor() {
|
||||
// this is for "fake" commands needed by AAPS MedtronicUITask
|
||||
}
|
||||
|
||||
constructor(code: Int, description: String, devices: MedtronicDeviceType?,
|
||||
parameterType: MinimedCommandParameterType?, cmd_params: ByteArray) : this(code, description, devices, parameterType, 0, 1, 0, 0, 11, 0) {
|
||||
commandParameters = cmd_params
|
||||
commandParametersCount = cmd_params.size
|
||||
}
|
||||
|
||||
// NEW
|
||||
constructor(code: Int, description: String, devices: MedtronicDeviceType?, //
|
||||
parameterType: MinimedCommandParameterType?, expectedLength: Int) : this(code, description, devices, parameterType, 64, 1, expectedLength, null) {
|
||||
}
|
||||
|
||||
// NEW
|
||||
constructor(code: Int, description: String, devices: MedtronicDeviceType?, //
|
||||
parameterType: MinimedCommandParameterType?, expectedLength: Int, resourceId: Int) : this(code, description, devices, parameterType, 64, 1, expectedLength, resourceId) {
|
||||
}
|
||||
|
||||
// NEW
|
||||
constructor(code: Int, description: String,
|
||||
devices: MedtronicDeviceType?, //
|
||||
parameterType: MinimedCommandParameterType?, recordLength: Int = 64, max_recs: Int = 1, expectedLength: Int = 0,
|
||||
resourceId: Int? = null) {
|
||||
commandCode = code.toByte()
|
||||
commandDescription = description
|
||||
this.devices = devices
|
||||
this.recordLength = recordLength
|
||||
maxRecords = max_recs
|
||||
this.resourceId = resourceId
|
||||
commandParametersCount = 0
|
||||
allowedRetries = 2
|
||||
this.parameterType = parameterType
|
||||
this.expectedLength = expectedLength
|
||||
if (this.parameterType == MinimedCommandParameterType.SubCommands) {
|
||||
minimalBufferSizeToStartReading = 200
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated("")
|
||||
constructor(code: Int, description: String, devices: MedtronicDeviceType?, //
|
||||
parameterType: MinimedCommandParameterType?, recordLength: Int, max_recs: Int, addy: Int, //
|
||||
addy_len: Int, cmd_type: Int, expectedLength: Int) {
|
||||
commandCode = code.toByte()
|
||||
commandDescription = description
|
||||
//this.targetType = targetType;
|
||||
this.devices = devices
|
||||
this.recordLength = recordLength
|
||||
maxRecords = max_recs
|
||||
command_type = cmd_type
|
||||
commandParametersCount = 0
|
||||
allowedRetries = 2
|
||||
this.parameterType = parameterType
|
||||
this.expectedLength = expectedLength
|
||||
if (this.parameterType == MinimedCommandParameterType.SubCommands) {
|
||||
minimalBufferSizeToStartReading = 200
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
return name
|
||||
}
|
||||
|
||||
enum class MinimedCommandParameterType {
|
||||
NoParameters, //
|
||||
FixedParameters, //
|
||||
SubCommands //
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs;
|
||||
|
||||
import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType;
|
||||
|
||||
/**
|
||||
* Created by andy on 11/3/18.
|
||||
*/
|
||||
|
||||
public enum MedtronicCustomActionType implements CustomActionType {
|
||||
|
||||
WakeUpAndTune(), //
|
||||
ClearBolusBlock(), //
|
||||
ResetRileyLinkConfiguration(), //
|
||||
;
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return this.name();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs
|
||||
|
||||
import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType
|
||||
|
||||
/**
|
||||
* Created by andy on 11/3/18.
|
||||
*/
|
||||
enum class MedtronicCustomActionType : CustomActionType {
|
||||
|
||||
WakeUpAndTune, //
|
||||
ClearBolusBlock, //
|
||||
ResetRileyLinkConfiguration;
|
||||
|
||||
//
|
||||
|
||||
override fun getKey(): String {
|
||||
return name
|
||||
}
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Taken from GNU Gluco Control diabetes management software (ggc.sourceforge.net)
|
||||
* <p>
|
||||
* Author: Andy {andy@atech-software.com}
|
||||
*/
|
||||
|
||||
public enum MedtronicDeviceType {
|
||||
Unknown_Device, //
|
||||
|
||||
// Pump
|
||||
Medtronic_511("511"), //
|
||||
|
||||
Medtronic_512("512"), //
|
||||
Medtronic_712("712"), //
|
||||
Medtronic_512_712(Medtronic_512, Medtronic_712), //
|
||||
|
||||
Medtronic_515("515"), //
|
||||
Medtronic_715("715"), //
|
||||
Medtronic_515_715(Medtronic_515, Medtronic_715), //
|
||||
|
||||
Medtronic_522("522"), //
|
||||
Medtronic_722("722"), //
|
||||
Medtronic_522_722(Medtronic_522, Medtronic_722), //
|
||||
|
||||
Medtronic_523_Revel("523"), //
|
||||
Medtronic_723_Revel("723"), //
|
||||
|
||||
Medtronic_554_Veo("554"), //
|
||||
Medtronic_754_Veo("754"), //
|
||||
|
||||
Medtronic_512andHigher(Medtronic_512, Medtronic_712, Medtronic_515, Medtronic_715, Medtronic_522, Medtronic_722, //
|
||||
Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo), //
|
||||
|
||||
Medtronic_515andHigher(Medtronic_515, Medtronic_715, Medtronic_522, Medtronic_722, Medtronic_523_Revel, Medtronic_723_Revel, //
|
||||
Medtronic_554_Veo, Medtronic_754_Veo), //
|
||||
Medtronic_522andHigher(Medtronic_522, Medtronic_722, Medtronic_523_Revel, Medtronic_723_Revel, //
|
||||
Medtronic_554_Veo, Medtronic_754_Veo), //
|
||||
Medtronic_523andHigher(Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, //
|
||||
Medtronic_754_Veo), //
|
||||
|
||||
Medtronic_554andHigher(Medtronic_554_Veo, Medtronic_754_Veo), //
|
||||
|
||||
|
||||
//
|
||||
All;
|
||||
|
||||
static Map<String, MedtronicDeviceType> mapByDescription;
|
||||
|
||||
static {
|
||||
|
||||
mapByDescription = new HashMap<>();
|
||||
|
||||
for (MedtronicDeviceType minimedDeviceType : values()) {
|
||||
|
||||
if (!minimedDeviceType.isFamily) {
|
||||
mapByDescription.put(minimedDeviceType.pumpModel, minimedDeviceType);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String pumpModel;
|
||||
|
||||
private final boolean isFamily;
|
||||
private MedtronicDeviceType[] familyMembers = null;
|
||||
|
||||
|
||||
MedtronicDeviceType(String pumpModel) {
|
||||
this.isFamily = false;
|
||||
this.pumpModel = pumpModel;
|
||||
}
|
||||
|
||||
|
||||
MedtronicDeviceType(MedtronicDeviceType... familyMembers) {
|
||||
this.familyMembers = familyMembers;
|
||||
this.isFamily = true;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isSameDevice(MedtronicDeviceType deviceWeCheck, MedtronicDeviceType deviceSources) {
|
||||
if (deviceSources.isFamily) {
|
||||
for (MedtronicDeviceType mdt : deviceSources.familyMembers) {
|
||||
if (mdt == deviceWeCheck)
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return (deviceWeCheck == deviceSources);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static MedtronicDeviceType getByDescription(String desc) {
|
||||
if (mapByDescription.containsKey(desc)) {
|
||||
return mapByDescription.get(desc);
|
||||
} else {
|
||||
return MedtronicDeviceType.Unknown_Device;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public static boolean isLargerFormat(MedtronicDeviceType model) {
|
||||
// return isSameDevice(model, Medtronic_523andHigher);
|
||||
// }
|
||||
|
||||
|
||||
public boolean isFamily() {
|
||||
return isFamily;
|
||||
}
|
||||
|
||||
|
||||
public MedtronicDeviceType[] getFamilyMembers() {
|
||||
return familyMembers;
|
||||
}
|
||||
|
||||
|
||||
// public boolean isLargerFormat() {
|
||||
// return isSameDevice(this, Medtronic_523andHigher);
|
||||
// }
|
||||
|
||||
public boolean isMedtronic_523orHigher() {
|
||||
return isSameDevice(this, Medtronic_523andHigher);
|
||||
}
|
||||
|
||||
|
||||
public int getBolusStrokes() {
|
||||
return (isMedtronic_523orHigher()) ? 40 : 10;
|
||||
}
|
||||
|
||||
|
||||
public String getPumpModel() {
|
||||
return pumpModel;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs
|
||||
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Taken from GNU Gluco Control diabetes management software (ggc.sourceforge.net)
|
||||
*
|
||||
*
|
||||
* Author: Andy {andy@atech-software.com}
|
||||
*/
|
||||
enum class MedtronicDeviceType {
|
||||
|
||||
Unknown_Device, //
|
||||
|
||||
// Pump
|
||||
Medtronic_511("511"), //
|
||||
Medtronic_512("512"), //
|
||||
Medtronic_712("712"), //
|
||||
Medtronic_512_712(Medtronic_512, Medtronic_712), //
|
||||
Medtronic_515("515"), //
|
||||
Medtronic_715("715"), //
|
||||
Medtronic_515_715(Medtronic_515, Medtronic_715), //
|
||||
Medtronic_522("522"), //
|
||||
Medtronic_722("722"), //
|
||||
Medtronic_522_722(Medtronic_522, Medtronic_722), //
|
||||
Medtronic_523_Revel("523"), //
|
||||
Medtronic_723_Revel("723"), //
|
||||
Medtronic_554_Veo("554"), //
|
||||
Medtronic_754_Veo("754"), //
|
||||
Medtronic_512andHigher(Medtronic_512, Medtronic_712, Medtronic_515, Medtronic_715, Medtronic_522, Medtronic_722, Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo), //
|
||||
Medtronic_515andHigher(Medtronic_515, Medtronic_715, Medtronic_522, Medtronic_722, Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo), //
|
||||
Medtronic_522andHigher(Medtronic_522, Medtronic_722, Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo), //
|
||||
Medtronic_523andHigher(Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo), //
|
||||
Medtronic_554andHigher(Medtronic_554_Veo, Medtronic_754_Veo), //
|
||||
|
||||
//
|
||||
All;
|
||||
|
||||
companion object {
|
||||
var mapByDescription: MutableMap<String, MedtronicDeviceType>? = null
|
||||
|
||||
@JvmStatic
|
||||
fun isSameDevice(deviceWeCheck: MedtronicDeviceType, deviceSources: MedtronicDeviceType): Boolean {
|
||||
if (deviceSources.isFamily) {
|
||||
for (mdt in deviceSources.familyMembers!!) {
|
||||
if (mdt == deviceWeCheck) return true
|
||||
}
|
||||
} else {
|
||||
return deviceWeCheck == deviceSources
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun getByDescription(desc: String): MedtronicDeviceType {
|
||||
return if (mapByDescription==null) {
|
||||
Unknown_Device
|
||||
} else if (mapByDescription!!.containsKey(desc)) {
|
||||
mapByDescription!![desc]!!
|
||||
} else {
|
||||
Unknown_Device
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
mapByDescription = HashMap()
|
||||
for (minimedDeviceType in values()) {
|
||||
if (!minimedDeviceType.isFamily) {
|
||||
mapByDescription!![minimedDeviceType.pumpModel!!] = minimedDeviceType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var pumpModel: String? = null
|
||||
private set
|
||||
|
||||
// public static boolean isLargerFormat(MedtronicDeviceType model) {
|
||||
// return isSameDevice(model, Medtronic_523andHigher);
|
||||
// }
|
||||
val isFamily: Boolean
|
||||
var familyMembers: Array<MedtronicDeviceType>? = null
|
||||
private set
|
||||
|
||||
constructor(pumpModel: String?) {
|
||||
isFamily = false
|
||||
this.pumpModel = pumpModel
|
||||
}
|
||||
|
||||
constructor(vararg familyMembers: MedtronicDeviceType) {
|
||||
this.familyMembers = familyMembers as Array<MedtronicDeviceType>?
|
||||
isFamily = true
|
||||
}
|
||||
|
||||
val isMedtronic_523orHigher: Boolean
|
||||
get() = isSameDevice(this, Medtronic_523andHigher)
|
||||
|
||||
val bolusStrokes: Int
|
||||
get() = if (isMedtronic_523orHigher) 40 else 10
|
||||
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs;
|
||||
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.R;
|
||||
|
||||
/**
|
||||
* Created by andy on 10/15/18.
|
||||
*/
|
||||
|
||||
public enum MedtronicNotificationType {
|
||||
|
||||
PumpUnreachable(Notification.RILEYLINK_CONNECTION, R.string.medtronic_pump_status_pump_unreachable, Notification.NORMAL), //
|
||||
PumpTypeNotSame(R.string.medtronic_error_pump_type_set_differs_from_detected, Notification.NORMAL), //
|
||||
PumpBasalProfilesNotEnabled(R.string.medtronic_error_pump_basal_profiles_not_enabled, Notification.URGENT), //
|
||||
PumpIncorrectBasalProfileSelected(R.string.medtronic_error_pump_incorrect_basal_profile_selected, Notification.URGENT), //
|
||||
PumpWrongTBRTypeSet(R.string.medtronic_error_pump_wrong_tbr_type_set, Notification.URGENT), //
|
||||
PumpWrongMaxBolusSet(R.string.medtronic_error_pump_wrong_max_bolus_set, Notification.NORMAL), //
|
||||
PumpWrongMaxBasalSet(R.string.medtronic_error_pump_wrong_max_basal_set, Notification.NORMAL), //
|
||||
PumpWrongTimeUrgent(R.string.medtronic_notification_check_time_date, Notification.URGENT),
|
||||
PumpWrongTimeNormal(R.string.medtronic_notification_check_time_date, Notification.NORMAL),
|
||||
TimeChangeOver24h(Notification.OVER_24H_TIME_CHANGE_REQUESTED, R.string.medtronic_error_pump_24h_time_change_requested, Notification.URGENT),
|
||||
//
|
||||
;
|
||||
|
||||
private int notificationType;
|
||||
private final int resourceId;
|
||||
private final int notificationUrgency;
|
||||
|
||||
|
||||
MedtronicNotificationType(int resourceId, int notificationUrgency) {
|
||||
this(Notification.MEDTRONIC_PUMP_ALARM, resourceId, notificationUrgency);
|
||||
}
|
||||
|
||||
|
||||
MedtronicNotificationType(int notificationType, int resourceId, int notificationUrgency) {
|
||||
this.notificationType = notificationType;
|
||||
this.resourceId = resourceId;
|
||||
this.notificationUrgency = notificationUrgency;
|
||||
}
|
||||
|
||||
|
||||
public int getNotificationType() {
|
||||
return notificationType;
|
||||
}
|
||||
|
||||
|
||||
public void setNotificationType(int notificationType) {
|
||||
this.notificationType = notificationType;
|
||||
}
|
||||
|
||||
|
||||
public int getResourceId() {
|
||||
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
|
||||
public int getNotificationUrgency() {
|
||||
|
||||
return notificationUrgency;
|
||||
}
|
||||
|
||||
// Notification.MEDTRONIC_PUMP_ALARM R.string.medtronic_pump_status_pump_unreachable, Notification.NORMAL
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs
|
||||
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.R
|
||||
|
||||
/**
|
||||
* Created by andy on 10/15/18.
|
||||
*/
|
||||
enum class MedtronicNotificationType(var notificationType: Int,
|
||||
val resourceId: Int,
|
||||
val notificationUrgency: Int) {
|
||||
|
||||
PumpUnreachable(Notification.RILEYLINK_CONNECTION, R.string.medtronic_pump_status_pump_unreachable, Notification.NORMAL), //
|
||||
PumpTypeNotSame(R.string.medtronic_error_pump_type_set_differs_from_detected, Notification.NORMAL), //
|
||||
PumpBasalProfilesNotEnabled(R.string.medtronic_error_pump_basal_profiles_not_enabled, Notification.URGENT), //
|
||||
PumpIncorrectBasalProfileSelected(R.string.medtronic_error_pump_incorrect_basal_profile_selected, Notification.URGENT), //
|
||||
PumpWrongTBRTypeSet(R.string.medtronic_error_pump_wrong_tbr_type_set, Notification.URGENT), //
|
||||
PumpWrongMaxBolusSet(R.string.medtronic_error_pump_wrong_max_bolus_set, Notification.NORMAL), //
|
||||
PumpWrongMaxBasalSet(R.string.medtronic_error_pump_wrong_max_basal_set, Notification.NORMAL), //
|
||||
PumpWrongTimeUrgent(R.string.medtronic_notification_check_time_date, Notification.URGENT), PumpWrongTimeNormal(R.string.medtronic_notification_check_time_date, Notification.NORMAL), TimeChangeOver24h(Notification.OVER_24H_TIME_CHANGE_REQUESTED, R.string.medtronic_error_pump_24h_time_change_requested, Notification.URGENT);
|
||||
|
||||
constructor(resourceId: Int, notificationUrgency: Int) : this(Notification.MEDTRONIC_PUMP_ALARM, resourceId, notificationUrgency) {}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs;
|
||||
|
||||
/**
|
||||
* Created by andy on 6/28/18.
|
||||
*/
|
||||
|
||||
public enum MedtronicStatusRefreshType {
|
||||
|
||||
PumpHistory(5, null), //
|
||||
Configuration(0, null), //
|
||||
RemainingInsulin(-1, MedtronicCommandType.GetRemainingInsulin), //
|
||||
BatteryStatus(55, MedtronicCommandType.GetBatteryStatus), //
|
||||
PumpTime(60, MedtronicCommandType.GetRealTimeClock) //
|
||||
;
|
||||
|
||||
private final int refreshTime;
|
||||
private final MedtronicCommandType commandType;
|
||||
|
||||
|
||||
MedtronicStatusRefreshType(int refreshTime, MedtronicCommandType commandType) {
|
||||
this.refreshTime = refreshTime;
|
||||
this.commandType = commandType;
|
||||
}
|
||||
|
||||
|
||||
public int getRefreshTime() {
|
||||
return refreshTime;
|
||||
}
|
||||
|
||||
|
||||
public MedtronicCommandType getCommandType(MedtronicDeviceType medtronicDeviceType) {
|
||||
if (this == Configuration) {
|
||||
return MedtronicCommandType.getSettings(medtronicDeviceType);
|
||||
} else
|
||||
return commandType;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs
|
||||
|
||||
/**
|
||||
* Created by andy on 6/28/18.
|
||||
*/
|
||||
enum class MedtronicStatusRefreshType(val refreshTime: Int,
|
||||
private val commandType: MedtronicCommandType?) {
|
||||
|
||||
PumpHistory(5, null), //
|
||||
Configuration(0, null), //
|
||||
RemainingInsulin(-1, MedtronicCommandType.GetRemainingInsulin), //
|
||||
BatteryStatus(55, MedtronicCommandType.GetBatteryStatus), //
|
||||
PumpTime(60, MedtronicCommandType.GetRealTimeClock //
|
||||
);
|
||||
|
||||
fun getCommandType(medtronicDeviceType: MedtronicDeviceType?): MedtronicCommandType? {
|
||||
return if (this == Configuration) {
|
||||
MedtronicCommandType.getSettings(medtronicDeviceType)
|
||||
} else
|
||||
commandType
|
||||
}
|
||||
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs;
|
||||
|
||||
/**
|
||||
* Created by andy on 10/18/18.
|
||||
*/
|
||||
|
||||
public enum MedtronicUIResponseType {
|
||||
|
||||
Data,
|
||||
Error,
|
||||
Invalid
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs
|
||||
|
||||
/**
|
||||
* Created by andy on 10/18/18.
|
||||
*/
|
||||
enum class MedtronicUIResponseType {
|
||||
|
||||
Data, Error, Invalid
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Application: GGC - GNU Gluco Control
|
||||
* Plug-in: Pump Tool (support for Pump devices)
|
||||
* <p>
|
||||
* See AUTHORS for copyright information.
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
|
||||
* version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* <p>
|
||||
* Filename: PumpBolusType Description: Pump Bolus Types
|
||||
* <p>
|
||||
* Author: Andy {andy@atech-software.com}
|
||||
*/
|
||||
|
||||
public enum PumpBolusType // implements CodeEnumWithTranslation
|
||||
{
|
||||
None(0, "NONE"), //
|
||||
Normal(1, "BOLUS_STANDARD"), //
|
||||
Audio(2, "BOLUS_AUDIO"), //
|
||||
Extended(3, "BOLUS_SQUARE", "AMOUNT_SQUARE=%s;DURATION=%s"), //
|
||||
Multiwave(4, "BOLUS_MULTIWAVE", "AMOUNT=%s;AMOUNT_SQUARE=%s;DURATION=%s");
|
||||
|
||||
static String[] descriptions;
|
||||
// static HashMap<String, CodeEnumWithTranslation> translationMapping = new HashMap<String,
|
||||
// CodeEnumWithTranslation>();
|
||||
static HashMap<Integer, PumpBolusType> codeMapping = new HashMap<Integer, PumpBolusType>();
|
||||
private static boolean translated;
|
||||
|
||||
static {
|
||||
for (PumpBolusType pbt : values()) {
|
||||
codeMapping.put(pbt.code, pbt);
|
||||
}
|
||||
}
|
||||
|
||||
// public static void translateKeywords(I18nControlAbstract ic)
|
||||
// {
|
||||
// if (translated)
|
||||
// return;
|
||||
//
|
||||
// for (PumpBolusType pbt : values())
|
||||
// {
|
||||
// pbt.setTranslation(ic.getMessage(pbt.i18nKey));
|
||||
// translationMapping.put(pbt.getTranslation(), pbt);
|
||||
// }
|
||||
//
|
||||
// String[] bolusDescriptions = { ic.getMessage("SELECT_BOLUS_TYPE"), //
|
||||
// ic.getMessage("BOLUS_STANDARD"), //
|
||||
// ic.getMessage("BOLUS_AUDIO"), //
|
||||
// ic.getMessage("BOLUS_SQUARE"), //
|
||||
// ic.getMessage("BOLUS_MULTIWAVE"), };
|
||||
//
|
||||
// descriptions = bolusDescriptions;
|
||||
//
|
||||
// translated = true;
|
||||
// }
|
||||
|
||||
int code;
|
||||
String i18nKey;
|
||||
String translation;
|
||||
String valueTemplate;
|
||||
|
||||
|
||||
PumpBolusType(int code, String i18nKey) {
|
||||
this.code = code;
|
||||
this.i18nKey = i18nKey;
|
||||
}
|
||||
|
||||
|
||||
PumpBolusType(int code, String i18nKey, String valueTemplate) {
|
||||
this.code = code;
|
||||
this.i18nKey = i18nKey;
|
||||
this.valueTemplate = valueTemplate;
|
||||
}
|
||||
|
||||
|
||||
public static PumpBolusType getByCode(int code) {
|
||||
if (codeMapping.containsKey(code)) {
|
||||
return codeMapping.get(code);
|
||||
} else {
|
||||
return PumpBolusType.None;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Descriptions (array)
|
||||
*
|
||||
* @return array of strings with description
|
||||
*/
|
||||
public static String[] getDescriptions() {
|
||||
return descriptions;
|
||||
}
|
||||
|
||||
|
||||
public String getTranslation() {
|
||||
return translation;
|
||||
}
|
||||
|
||||
|
||||
public void setTranslation(String translation) {
|
||||
this.translation = translation;
|
||||
}
|
||||
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
public String getI18nKey() {
|
||||
return i18nKey;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return this.name();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs
|
||||
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
enum class PumpBolusType {
|
||||
|
||||
None(0, "NONE"), //
|
||||
Normal(1, "BOLUS_STANDARD"), //
|
||||
Audio(2, "BOLUS_AUDIO"), //
|
||||
Extended(3, "BOLUS_SQUARE", "AMOUNT_SQUARE=%s;DURATION=%s"), //
|
||||
Multiwave(4, "BOLUS_MULTIWAVE", "AMOUNT=%s;AMOUNT_SQUARE=%s;DURATION=%s");
|
||||
|
||||
companion object {
|
||||
var codeMapping = HashMap<Int, PumpBolusType?>()
|
||||
|
||||
fun getByCode(code: Int): PumpBolusType? {
|
||||
return if (codeMapping.containsKey(code)) {
|
||||
codeMapping[code]
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
for (pbt in values()) {
|
||||
codeMapping[pbt.code] = pbt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var code: Int
|
||||
var i18nKey: String
|
||||
var valueTemplate: String? = null
|
||||
|
||||
constructor(code: Int, i18nKey: String) {
|
||||
this.code = code
|
||||
this.i18nKey = i18nKey
|
||||
}
|
||||
|
||||
constructor(code: Int, i18nKey: String, valueTemplate: String?) {
|
||||
this.code = code
|
||||
this.i18nKey = i18nKey
|
||||
this.valueTemplate = valueTemplate
|
||||
}
|
||||
|
||||
//override val name: String
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs;
|
||||
|
||||
/**
|
||||
* Created by andy on 27.02.15.
|
||||
*/
|
||||
public enum PumpConfigurationGroup {
|
||||
General(1, "GROUP_GENERAL"), //
|
||||
Device(2, "GROUP_DEVICE"), //
|
||||
|
||||
Insulin(3, "GROUP_INSULIN"), //
|
||||
|
||||
Basal(4, "GROUP_BASAL"), //
|
||||
Bolus(5, "GROUP_BOLUS"), //
|
||||
Sound(6, "GROUP_SOUND"), //
|
||||
|
||||
Other(20, "GROUP_OTHER"), //
|
||||
|
||||
UnknownGroup(21, "GROUP_UNKNOWN"), //
|
||||
|
||||
; //
|
||||
|
||||
static boolean translated;
|
||||
int code;
|
||||
String i18nKey;
|
||||
String translation;
|
||||
|
||||
|
||||
PumpConfigurationGroup(int code, String i18nKey) {
|
||||
this.code = code;
|
||||
this.i18nKey = i18nKey;
|
||||
}
|
||||
|
||||
|
||||
public String getTranslation() {
|
||||
return translation;
|
||||
}
|
||||
|
||||
|
||||
public void setTranslation(String translation) {
|
||||
this.translation = translation;
|
||||
}
|
||||
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
public String getI18nKey() {
|
||||
return i18nKey;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return this.name();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.defs
|
||||
|
||||
/**
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
enum class PumpConfigurationGroup(var code: Int) {
|
||||
|
||||
General(1), //
|
||||
Device(2), //
|
||||
Insulin(3), //
|
||||
Basal(4), //
|
||||
Bolus(5), //
|
||||
Sound(6), //
|
||||
Other(20), //
|
||||
UnknownGroup(21);
|
||||
|
||||
}
|
|
@ -1,180 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.driver;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
|
||||
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BasalProfileStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BatteryType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||
|
||||
|
||||
/**
|
||||
* Created by andy on 4/28/18.
|
||||
*/
|
||||
|
||||
@Singleton
|
||||
public class MedtronicPumpStatus extends info.nightscout.androidaps.plugins.pump.common.data.PumpStatus {
|
||||
|
||||
private final ResourceHelper resourceHelper;
|
||||
private final SP sp;
|
||||
private final RileyLinkUtil rileyLinkUtil;
|
||||
private final RxBusWrapper rxBus;
|
||||
|
||||
public String errorDescription = null;
|
||||
public String serialNumber;
|
||||
public String pumpFrequency = null;
|
||||
public Double maxBolus;
|
||||
public Double maxBasal;
|
||||
|
||||
// statuses
|
||||
private PumpDeviceState pumpDeviceState = PumpDeviceState.NeverContacted;
|
||||
public MedtronicDeviceType medtronicDeviceType = null;
|
||||
public Date tempBasalStart;
|
||||
public Double tempBasalAmount = 0.0d;
|
||||
|
||||
// fixme
|
||||
public Integer tempBasalLength = 0;
|
||||
|
||||
private Map<String, PumpType> medtronicPumpMap = null;
|
||||
private Map<String, MedtronicDeviceType> medtronicDeviceTypeMap = null;
|
||||
public BasalProfileStatus basalProfileStatus = BasalProfileStatus.NotInitialized;
|
||||
public BatteryType batteryType = BatteryType.None;
|
||||
|
||||
|
||||
@Inject
|
||||
public MedtronicPumpStatus(ResourceHelper resourceHelper,
|
||||
SP sp,
|
||||
RxBusWrapper rxBus,
|
||||
RileyLinkUtil rileyLinkUtil
|
||||
) {
|
||||
super(PumpType.MEDTRONIC_522_722);
|
||||
this.resourceHelper = resourceHelper;
|
||||
this.sp = sp;
|
||||
this.rxBus = rxBus;
|
||||
this.rileyLinkUtil = rileyLinkUtil;
|
||||
initSettings();
|
||||
}
|
||||
|
||||
|
||||
public void initSettings() {
|
||||
|
||||
this.activeProfileName = "STD";
|
||||
this.reservoirRemainingUnits = 75d;
|
||||
this.batteryRemaining = 75;
|
||||
|
||||
if (this.medtronicPumpMap == null)
|
||||
createMedtronicPumpMap();
|
||||
|
||||
if (this.medtronicDeviceTypeMap == null)
|
||||
createMedtronicDeviceTypeMap();
|
||||
|
||||
this.lastConnection = sp.getLong(MedtronicConst.Statistics.LastGoodPumpCommunicationTime, 0L);
|
||||
this.lastDataTime = this.lastConnection;
|
||||
}
|
||||
|
||||
|
||||
private void createMedtronicDeviceTypeMap() {
|
||||
medtronicDeviceTypeMap = new HashMap<>();
|
||||
medtronicDeviceTypeMap.put("512", MedtronicDeviceType.Medtronic_512);
|
||||
medtronicDeviceTypeMap.put("712", MedtronicDeviceType.Medtronic_712);
|
||||
medtronicDeviceTypeMap.put("515", MedtronicDeviceType.Medtronic_515);
|
||||
medtronicDeviceTypeMap.put("715", MedtronicDeviceType.Medtronic_715);
|
||||
|
||||
medtronicDeviceTypeMap.put("522", MedtronicDeviceType.Medtronic_522);
|
||||
medtronicDeviceTypeMap.put("722", MedtronicDeviceType.Medtronic_722);
|
||||
medtronicDeviceTypeMap.put("523", MedtronicDeviceType.Medtronic_523_Revel);
|
||||
medtronicDeviceTypeMap.put("723", MedtronicDeviceType.Medtronic_723_Revel);
|
||||
medtronicDeviceTypeMap.put("554", MedtronicDeviceType.Medtronic_554_Veo);
|
||||
medtronicDeviceTypeMap.put("754", MedtronicDeviceType.Medtronic_754_Veo);
|
||||
}
|
||||
|
||||
|
||||
private void createMedtronicPumpMap() {
|
||||
|
||||
medtronicPumpMap = new HashMap<>();
|
||||
medtronicPumpMap.put("512", PumpType.MEDTRONIC_512_712);
|
||||
medtronicPumpMap.put("712", PumpType.MEDTRONIC_512_712);
|
||||
medtronicPumpMap.put("515", PumpType.MEDTRONIC_515_715);
|
||||
medtronicPumpMap.put("715", PumpType.MEDTRONIC_515_715);
|
||||
|
||||
medtronicPumpMap.put("522", PumpType.MEDTRONIC_522_722);
|
||||
medtronicPumpMap.put("722", PumpType.MEDTRONIC_522_722);
|
||||
medtronicPumpMap.put("523", PumpType.MEDTRONIC_523_723_REVEL);
|
||||
medtronicPumpMap.put("723", PumpType.MEDTRONIC_523_723_REVEL);
|
||||
medtronicPumpMap.put("554", PumpType.MEDTRONIC_554_754_VEO);
|
||||
medtronicPumpMap.put("754", PumpType.MEDTRONIC_554_754_VEO);
|
||||
|
||||
}
|
||||
|
||||
public Map<String, PumpType> getMedtronicPumpMap() {
|
||||
return medtronicPumpMap;
|
||||
}
|
||||
|
||||
public Map<String, MedtronicDeviceType> getMedtronicDeviceTypeMap() {
|
||||
return medtronicDeviceTypeMap;
|
||||
}
|
||||
|
||||
public double getBasalProfileForHour() {
|
||||
if (basalsByHour != null) {
|
||||
GregorianCalendar c = new GregorianCalendar();
|
||||
int hour = c.get(Calendar.HOUR_OF_DAY);
|
||||
|
||||
return basalsByHour[hour];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Battery type
|
||||
private Map<String, BatteryType> mapByDescription;
|
||||
|
||||
public BatteryType getBatteryTypeByDescription(String batteryTypeStr) {
|
||||
if (mapByDescription == null) {
|
||||
mapByDescription = new HashMap<>();
|
||||
for (BatteryType value : BatteryType.values()) {
|
||||
mapByDescription.put(resourceHelper.gs(value.description), value);
|
||||
}
|
||||
}
|
||||
if (mapByDescription.containsKey(batteryTypeStr)) {
|
||||
return mapByDescription.get(batteryTypeStr);
|
||||
}
|
||||
return BatteryType.None;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getErrorInfo() {
|
||||
return (errorDescription == null) ? "-" : errorDescription;
|
||||
}
|
||||
|
||||
|
||||
public PumpDeviceState getPumpDeviceState() {
|
||||
return pumpDeviceState;
|
||||
}
|
||||
|
||||
|
||||
public void setPumpDeviceState(PumpDeviceState pumpDeviceState) {
|
||||
this.pumpDeviceState = pumpDeviceState;
|
||||
|
||||
rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItem(pumpDeviceState, RileyLinkTargetDevice.MedtronicPump));
|
||||
|
||||
rxBus.send(new EventRileyLinkDeviceStatusChange(pumpDeviceState));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.driver
|
||||
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BasalProfileStatus
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BatteryType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Created by andy on 4/28/18.
|
||||
*/
|
||||
@Singleton
|
||||
class MedtronicPumpStatus @Inject constructor(private val resourceHelper: ResourceHelper,
|
||||
private val sp: SP,
|
||||
private val rxBus: RxBusWrapper,
|
||||
private val rileyLinkUtil: RileyLinkUtil
|
||||
) : PumpStatus(PumpType.MEDTRONIC_522_722) {
|
||||
|
||||
var errorDescription: String? = null
|
||||
var serialNumber: String? = null
|
||||
var pumpFrequency: String? = null
|
||||
var maxBolus: Double? = null
|
||||
var maxBasal: Double? = null
|
||||
|
||||
// statuses
|
||||
var pumpDeviceState = PumpDeviceState.NeverContacted
|
||||
set(pumpDeviceState) {
|
||||
field = pumpDeviceState
|
||||
rileyLinkUtil.rileyLinkHistory.add(RLHistoryItem(pumpDeviceState, RileyLinkTargetDevice.MedtronicPump))
|
||||
rxBus.send(EventRileyLinkDeviceStatusChange(pumpDeviceState))
|
||||
}
|
||||
var medtronicDeviceType: MedtronicDeviceType? = null
|
||||
|
||||
// fixme
|
||||
var medtronicPumpMap: MutableMap<String, PumpType> = HashMap()
|
||||
var medtronicDeviceTypeMap: MutableMap<String, MedtronicDeviceType> = HashMap()
|
||||
var basalProfileStatus = BasalProfileStatus.NotInitialized
|
||||
var batteryType = BatteryType.None
|
||||
|
||||
override fun initSettings() {
|
||||
activeProfileName = "STD"
|
||||
reservoirRemainingUnits = 75.0
|
||||
batteryRemaining = 75
|
||||
if (medtronicPumpMap.isEmpty()) createMedtronicPumpMap()
|
||||
if (medtronicDeviceTypeMap.isEmpty()) createMedtronicDeviceTypeMap()
|
||||
lastConnection = sp.getLong(MedtronicConst.Statistics.LastGoodPumpCommunicationTime, 0L)
|
||||
lastDataTime = lastConnection
|
||||
}
|
||||
|
||||
private fun createMedtronicDeviceTypeMap() {
|
||||
medtronicDeviceTypeMap["512"] = MedtronicDeviceType.Medtronic_512
|
||||
medtronicDeviceTypeMap["712"] = MedtronicDeviceType.Medtronic_712
|
||||
medtronicDeviceTypeMap["515"] = MedtronicDeviceType.Medtronic_515
|
||||
medtronicDeviceTypeMap["715"] = MedtronicDeviceType.Medtronic_715
|
||||
medtronicDeviceTypeMap["522"] = MedtronicDeviceType.Medtronic_522
|
||||
medtronicDeviceTypeMap["722"] = MedtronicDeviceType.Medtronic_722
|
||||
medtronicDeviceTypeMap["523"] = MedtronicDeviceType.Medtronic_523_Revel
|
||||
medtronicDeviceTypeMap["723"] = MedtronicDeviceType.Medtronic_723_Revel
|
||||
medtronicDeviceTypeMap["554"] = MedtronicDeviceType.Medtronic_554_Veo
|
||||
medtronicDeviceTypeMap["754"] = MedtronicDeviceType.Medtronic_754_Veo
|
||||
}
|
||||
|
||||
private fun createMedtronicPumpMap() {
|
||||
medtronicPumpMap = HashMap()
|
||||
medtronicPumpMap["512"] = PumpType.MEDTRONIC_512_712
|
||||
medtronicPumpMap["712"] = PumpType.MEDTRONIC_512_712
|
||||
medtronicPumpMap["515"] = PumpType.MEDTRONIC_515_715
|
||||
medtronicPumpMap["715"] = PumpType.MEDTRONIC_515_715
|
||||
medtronicPumpMap["522"] = PumpType.MEDTRONIC_522_722
|
||||
medtronicPumpMap["722"] = PumpType.MEDTRONIC_522_722
|
||||
medtronicPumpMap["523"] = PumpType.MEDTRONIC_523_723_REVEL
|
||||
medtronicPumpMap["723"] = PumpType.MEDTRONIC_523_723_REVEL
|
||||
medtronicPumpMap["554"] = PumpType.MEDTRONIC_554_754_VEO
|
||||
medtronicPumpMap["754"] = PumpType.MEDTRONIC_554_754_VEO
|
||||
}
|
||||
|
||||
|
||||
val basalProfileForHour: Double
|
||||
get() {
|
||||
if (basalsByHour != null) {
|
||||
val c = GregorianCalendar()
|
||||
val hour = c[Calendar.HOUR_OF_DAY]
|
||||
return basalsByHour!![hour]
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
// Battery type
|
||||
private var mapByDescription: MutableMap<String, BatteryType?> = HashMap()
|
||||
|
||||
fun getBatteryTypeByDescription(batteryTypeStr: String?): BatteryType? {
|
||||
if (mapByDescription.size == 0) {
|
||||
for (value in BatteryType.values()) {
|
||||
mapByDescription[resourceHelper.gs(value.description)] = value
|
||||
}
|
||||
}
|
||||
return if (mapByDescription.containsKey(batteryTypeStr)) {
|
||||
mapByDescription[batteryTypeStr]
|
||||
} else BatteryType.None
|
||||
}
|
||||
|
||||
override val errorInfo: String
|
||||
get() = if (errorDescription == null) "-" else errorDescription!!
|
||||
|
||||
|
||||
val tbrRemainingTime: Int?
|
||||
get() {
|
||||
if (tempBasalStart == null) return null
|
||||
if (tempBasalEnd == null) {
|
||||
val startTime = tempBasalStart!!.time
|
||||
tempBasalEnd = startTime + tempBasalLength!! * 60 * 1000
|
||||
}
|
||||
if (System.currentTimeMillis() > tempBasalEnd!!) {
|
||||
tempBasalStart = null
|
||||
tempBasalEnd = null
|
||||
tempBasalLength = null
|
||||
tempBasalAmount = null
|
||||
return null
|
||||
}
|
||||
val timeMinutes = (tempBasalEnd!! - System.currentTimeMillis()) / (1000 * 60)
|
||||
return timeMinutes.toInt()
|
||||
}
|
||||
|
||||
init {
|
||||
initSettings()
|
||||
}
|
||||
}
|
|
@ -1,388 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.service;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkTargetFrequency;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkService;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.R;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIComm;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIPostprocessor;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BatteryType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
|
||||
/**
|
||||
* RileyLinkMedtronicService is intended to stay running when the gui-app is closed.
|
||||
*/
|
||||
@Singleton
|
||||
public class RileyLinkMedtronicService extends RileyLinkService {
|
||||
|
||||
@Inject MedtronicPumpPlugin medtronicPumpPlugin;
|
||||
@Inject MedtronicUtil medtronicUtil;
|
||||
@Inject MedtronicUIPostprocessor medtronicUIPostprocessor;
|
||||
@Inject MedtronicPumpStatus medtronicPumpStatus;
|
||||
@Inject RFSpy rfSpy;
|
||||
@Inject MedtronicCommunicationManager medtronicCommunicationManager;
|
||||
|
||||
private MedtronicUIComm medtronicUIComm;
|
||||
private final IBinder mBinder = new LocalBinder();
|
||||
|
||||
private boolean serialChanged = false;
|
||||
private String[] frequencies;
|
||||
private String rileyLinkAddress = null;
|
||||
private boolean rileyLinkAddressChanged = false;
|
||||
private RileyLinkEncodingType encodingType;
|
||||
private boolean encodingChanged = false;
|
||||
private boolean inPreInit = true;
|
||||
|
||||
|
||||
// This empty constructor must be kept, otherwise dagger injection might break!
|
||||
@Inject
|
||||
public RileyLinkMedtronicService() {
|
||||
}
|
||||
|
||||
|
||||
@Override public void onCreate() {
|
||||
super.onCreate();
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly created");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
aapsLogger.warn(LTag.PUMPCOMM, "onConfigurationChanged");
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RileyLinkEncodingType getEncoding() {
|
||||
return RileyLinkEncodingType.FourByteSixByteLocal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If you have customized RileyLinkServiceData you need to override this
|
||||
*/
|
||||
public void initRileyLinkServiceData() {
|
||||
|
||||
frequencies = new String[2];
|
||||
frequencies[0] = resourceHelper.gs(R.string.key_medtronic_pump_frequency_us_ca);
|
||||
frequencies[1] = resourceHelper.gs(R.string.key_medtronic_pump_frequency_worldwide);
|
||||
|
||||
rileyLinkServiceData.targetDevice = RileyLinkTargetDevice.MedtronicPump;
|
||||
|
||||
setPumpIDString(sp.getString(MedtronicConst.Prefs.PumpSerial, "000000"));
|
||||
|
||||
// get most recently used RileyLink address and name
|
||||
rileyLinkServiceData.rileyLinkAddress = sp.getString(RileyLinkConst.Prefs.RileyLinkAddress, "");
|
||||
rileyLinkServiceData.rileyLinkName = sp.getString(RileyLinkConst.Prefs.RileyLinkName, "");
|
||||
|
||||
rfspy.startReader();
|
||||
|
||||
medtronicUIComm = new MedtronicUIComm(injector, aapsLogger, medtronicUtil, medtronicUIPostprocessor, medtronicCommunicationManager);
|
||||
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly constructed");
|
||||
}
|
||||
|
||||
public MedtronicCommunicationManager getDeviceCommunicationManager() {
|
||||
return this.medtronicCommunicationManager;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setPumpDeviceState(PumpDeviceState pumpDeviceState) {
|
||||
this.medtronicPumpStatus.setPumpDeviceState(pumpDeviceState);
|
||||
}
|
||||
|
||||
|
||||
public MedtronicUIComm getMedtronicUIComm() {
|
||||
return medtronicUIComm;
|
||||
}
|
||||
|
||||
public void setPumpIDString(String pumpID) {
|
||||
if (pumpID.length() != 6) {
|
||||
aapsLogger.error("setPumpIDString: invalid pump id string: " + pumpID);
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] pumpIDBytes = ByteUtil.fromHexString(pumpID);
|
||||
|
||||
if (pumpIDBytes == null) {
|
||||
aapsLogger.error("Invalid pump ID? - PumpID is null.");
|
||||
|
||||
rileyLinkServiceData.setPumpID("000000", new byte[]{0, 0, 0});
|
||||
|
||||
} else if (pumpIDBytes.length != 3) {
|
||||
aapsLogger.error("Invalid pump ID? " + ByteUtil.shortHexString(pumpIDBytes));
|
||||
|
||||
rileyLinkServiceData.setPumpID("000000", new byte[]{0, 0, 0});
|
||||
|
||||
} else if (pumpID.equals("000000")) {
|
||||
aapsLogger.error("Using pump ID " + pumpID);
|
||||
|
||||
rileyLinkServiceData.setPumpID(pumpID, new byte[]{0, 0, 0});
|
||||
|
||||
} else {
|
||||
aapsLogger.info(LTag.PUMPBTCOMM, "Using pump ID " + pumpID);
|
||||
|
||||
String oldId = rileyLinkServiceData.pumpID;
|
||||
|
||||
rileyLinkServiceData.setPumpID(pumpID, pumpIDBytes);
|
||||
|
||||
if (oldId != null && !oldId.equals(pumpID)) {
|
||||
medtronicUtil.setMedtronicPumpModel(null); // if we change pumpId, model probably changed too
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
medtronicPumpStatus.setPumpDeviceState(PumpDeviceState.InvalidConfiguration);
|
||||
|
||||
// LOG.info("setPumpIDString: saved pumpID " + idString);
|
||||
}
|
||||
|
||||
public class LocalBinder extends Binder {
|
||||
|
||||
public RileyLinkMedtronicService getServiceInstance() {
|
||||
return RileyLinkMedtronicService.this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
// PumpInterface - REMOVE
|
||||
|
||||
public boolean isInitialized() {
|
||||
return rileyLinkServiceData.rileyLinkServiceState.isReady();
|
||||
}
|
||||
|
||||
|
||||
public boolean verifyConfiguration(boolean forceRileyLinkAddressRenewal) {
|
||||
try {
|
||||
String regexSN = "[0-9]{6}";
|
||||
String regexMac = "([\\da-fA-F]{1,2}(?::|$)){6}";
|
||||
|
||||
medtronicPumpStatus.errorDescription = "-";
|
||||
|
||||
String serialNr = sp.getStringOrNull(MedtronicConst.Prefs.PumpSerial, null);
|
||||
|
||||
if (serialNr == null) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_serial_not_set);
|
||||
return false;
|
||||
} else {
|
||||
if (!serialNr.matches(regexSN)) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_serial_invalid);
|
||||
return false;
|
||||
} else {
|
||||
if (!serialNr.equals(medtronicPumpStatus.serialNumber)) {
|
||||
medtronicPumpStatus.serialNumber = serialNr;
|
||||
serialChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String pumpTypePref = sp.getStringOrNull(MedtronicConst.Prefs.PumpType, null);
|
||||
|
||||
if (pumpTypePref == null) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_pump_type_not_set);
|
||||
return false;
|
||||
} else {
|
||||
String pumpTypePart = pumpTypePref.substring(0, 3);
|
||||
|
||||
if (!pumpTypePart.matches("[0-9]{3}")) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_pump_type_invalid);
|
||||
return false;
|
||||
} else {
|
||||
PumpType pumpType = medtronicPumpStatus.getMedtronicPumpMap().get(pumpTypePart);
|
||||
medtronicPumpStatus.medtronicDeviceType = medtronicPumpStatus.getMedtronicDeviceTypeMap().get(pumpTypePart);
|
||||
medtronicPumpPlugin.setPumpType(pumpType);
|
||||
|
||||
if (pumpTypePart.startsWith("7"))
|
||||
medtronicPumpStatus.reservoirFullUnits = 300;
|
||||
else
|
||||
medtronicPumpStatus.reservoirFullUnits = 176;
|
||||
}
|
||||
}
|
||||
|
||||
String pumpFrequency = sp.getStringOrNull(MedtronicConst.Prefs.PumpFrequency, null);
|
||||
|
||||
if (pumpFrequency == null) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_pump_frequency_not_set);
|
||||
return false;
|
||||
} else {
|
||||
if (!pumpFrequency.equals(frequencies[0]) && !pumpFrequency.equals(frequencies[1])) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_pump_frequency_invalid);
|
||||
return false;
|
||||
} else {
|
||||
medtronicPumpStatus.pumpFrequency = pumpFrequency;
|
||||
boolean isFrequencyUS = pumpFrequency.equals(frequencies[0]);
|
||||
|
||||
RileyLinkTargetFrequency newTargetFrequency = isFrequencyUS ? //
|
||||
RileyLinkTargetFrequency.Medtronic_US
|
||||
: RileyLinkTargetFrequency.Medtronic_WorldWide;
|
||||
|
||||
if (rileyLinkServiceData.rileyLinkTargetFrequency != newTargetFrequency) {
|
||||
rileyLinkServiceData.rileyLinkTargetFrequency = newTargetFrequency;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
String rileyLinkAddress = sp.getStringOrNull(RileyLinkConst.Prefs.RileyLinkAddress, null);
|
||||
|
||||
if (rileyLinkAddress == null) {
|
||||
aapsLogger.debug(LTag.PUMP, "RileyLink address invalid: null");
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_rileylink_address_invalid);
|
||||
return false;
|
||||
} else {
|
||||
if (!rileyLinkAddress.matches(regexMac)) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_rileylink_address_invalid);
|
||||
aapsLogger.debug(LTag.PUMP, "RileyLink address invalid: %s", rileyLinkAddress);
|
||||
} else {
|
||||
if (!rileyLinkAddress.equals(this.rileyLinkAddress)) {
|
||||
this.rileyLinkAddress = rileyLinkAddress;
|
||||
rileyLinkAddressChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double maxBolusLcl = checkParameterValue(MedtronicConst.Prefs.MaxBolus, "25.0", 25.0d);
|
||||
|
||||
if (medtronicPumpStatus.maxBolus == null || !medtronicPumpStatus.maxBolus.equals(maxBolusLcl)) {
|
||||
medtronicPumpStatus.maxBolus = maxBolusLcl;
|
||||
|
||||
//LOG.debug("Max Bolus from AAPS settings is " + maxBolus);
|
||||
}
|
||||
|
||||
double maxBasalLcl = checkParameterValue(MedtronicConst.Prefs.MaxBasal, "35.0", 35.0d);
|
||||
|
||||
if (medtronicPumpStatus.maxBasal == null || !medtronicPumpStatus.maxBasal.equals(maxBasalLcl)) {
|
||||
medtronicPumpStatus.maxBasal = maxBasalLcl;
|
||||
|
||||
//LOG.debug("Max Basal from AAPS settings is " + maxBasal);
|
||||
}
|
||||
|
||||
|
||||
String encodingTypeStr = sp.getStringOrNull(MedtronicConst.Prefs.Encoding, null);
|
||||
|
||||
if (encodingTypeStr == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RileyLinkEncodingType newEncodingType = RileyLinkEncodingType.getByDescription(encodingTypeStr, resourceHelper);
|
||||
|
||||
if (encodingType == null) {
|
||||
encodingType = newEncodingType;
|
||||
} else if (encodingType != newEncodingType) {
|
||||
encodingType = newEncodingType;
|
||||
encodingChanged = true;
|
||||
}
|
||||
|
||||
String batteryTypeStr = sp.getStringOrNull(MedtronicConst.Prefs.BatteryType, null);
|
||||
|
||||
if (batteryTypeStr == null)
|
||||
return false;
|
||||
|
||||
BatteryType batteryType = medtronicPumpStatus.getBatteryTypeByDescription(batteryTypeStr);
|
||||
|
||||
if (medtronicPumpStatus.batteryType != batteryType) {
|
||||
medtronicPumpStatus.batteryType = batteryType;
|
||||
}
|
||||
|
||||
//String bolusDebugEnabled = sp.getStringOrNull(MedtronicConst.Prefs.BolusDebugEnabled, null);
|
||||
//boolean bolusDebug = bolusDebugEnabled != null && bolusDebugEnabled.equals(resourceHelper.gs(R.string.common_on));
|
||||
//MedtronicHistoryData.doubleBolusDebug = bolusDebug;
|
||||
|
||||
rileyLinkServiceData.showBatteryLevel = sp.getBoolean(RileyLinkConst.Prefs.ShowBatteryLevel, false);
|
||||
|
||||
reconfigureService(forceRileyLinkAddressRenewal);
|
||||
|
||||
return true;
|
||||
|
||||
} catch (Exception ex) {
|
||||
medtronicPumpStatus.errorDescription = ex.getMessage();
|
||||
aapsLogger.error(LTag.PUMP, "Error on Verification: " + ex.getMessage(), ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean reconfigureService(boolean forceRileyLinkAddressRenewal) {
|
||||
|
||||
if (!inPreInit) {
|
||||
|
||||
if (serialChanged) {
|
||||
setPumpIDString(medtronicPumpStatus.serialNumber); // short operation
|
||||
serialChanged = false;
|
||||
}
|
||||
|
||||
if (rileyLinkAddressChanged || forceRileyLinkAddressRenewal) {
|
||||
rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.RileyLinkNewAddressSet, this);
|
||||
rileyLinkAddressChanged = false;
|
||||
}
|
||||
|
||||
if (encodingChanged) {
|
||||
changeRileyLinkEncoding(encodingType);
|
||||
encodingChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if (targetFrequencyChanged && !inPreInit && MedtronicUtil.getMedtronicService() != null) {
|
||||
// RileyLinkUtil.setRileyLinkTargetFrequency(targetFrequency);
|
||||
// // RileyLinkUtil.getRileyLinkCommunicationManager().refreshRileyLinkTargetFrequency();
|
||||
// targetFrequencyChanged = false;
|
||||
// }
|
||||
|
||||
return (!rileyLinkAddressChanged && !serialChanged && !encodingChanged); // && !targetFrequencyChanged);
|
||||
}
|
||||
|
||||
private double checkParameterValue(int key, String defaultValue, double defaultValueDouble) {
|
||||
double val;
|
||||
|
||||
String value = sp.getString(key, defaultValue);
|
||||
|
||||
try {
|
||||
val = Double.parseDouble(value);
|
||||
} catch (Exception ex) {
|
||||
aapsLogger.error("Error parsing setting: %s, value found %s", key, value);
|
||||
val = defaultValueDouble;
|
||||
}
|
||||
|
||||
if (val > defaultValueDouble) {
|
||||
sp.putString(key, defaultValue);
|
||||
val = defaultValueDouble;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public boolean setNotInPreInit() {
|
||||
this.inPreInit = false;
|
||||
|
||||
return reconfigureService(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,289 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.service
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.os.Binder
|
||||
import android.os.IBinder
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkTargetFrequency
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkService
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.R
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIComm
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIPostprocessor
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.service.RileyLinkMedtronicService
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* RileyLinkMedtronicService is intended to stay running when the gui-app is closed.
|
||||
*/
|
||||
@Singleton
|
||||
class RileyLinkMedtronicService // This empty constructor must be kept, otherwise dagger injection might break!
|
||||
@Inject constructor() : RileyLinkService() {
|
||||
|
||||
@Inject lateinit var medtronicPumpPlugin: MedtronicPumpPlugin
|
||||
@Inject lateinit var medtronicUtil: MedtronicUtil
|
||||
@Inject lateinit var medtronicUIPostprocessor: MedtronicUIPostprocessor
|
||||
@Inject lateinit var medtronicPumpStatus: MedtronicPumpStatus
|
||||
@Inject lateinit var rfSpy: RFSpy
|
||||
@Inject lateinit var medtronicCommunicationManager: MedtronicCommunicationManager
|
||||
|
||||
var medtronicUIComm: MedtronicUIComm? = null
|
||||
private set
|
||||
private val mBinder: IBinder = LocalBinder()
|
||||
private var serialChanged = false
|
||||
private var frequencies: Array<String?>? = null
|
||||
private var rileyLinkAddress: String? = null
|
||||
private var rileyLinkAddressChanged = false
|
||||
private var encodingType: RileyLinkEncodingType? = null
|
||||
private var encodingChanged = false
|
||||
private var inPreInit = true
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly created")
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
aapsLogger.warn(LTag.PUMPCOMM, "onConfigurationChanged")
|
||||
super.onConfigurationChanged(newConfig)
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder {
|
||||
return mBinder
|
||||
}
|
||||
|
||||
override fun getEncoding(): RileyLinkEncodingType {
|
||||
return RileyLinkEncodingType.FourByteSixByteLocal
|
||||
}
|
||||
|
||||
/**
|
||||
* If you have customized RileyLinkServiceData you need to override this
|
||||
*/
|
||||
override fun initRileyLinkServiceData() {
|
||||
frequencies = arrayOfNulls(2)
|
||||
frequencies!![0] = resourceHelper.gs(R.string.key_medtronic_pump_frequency_us_ca)
|
||||
frequencies!![1] = resourceHelper.gs(R.string.key_medtronic_pump_frequency_worldwide)
|
||||
rileyLinkServiceData.targetDevice = RileyLinkTargetDevice.MedtronicPump
|
||||
setPumpIDString(sp.getString(MedtronicConst.Prefs.PumpSerial, "000000"))
|
||||
|
||||
// get most recently used RileyLink address and name
|
||||
rileyLinkServiceData.rileyLinkAddress = sp.getString(RileyLinkConst.Prefs.RileyLinkAddress, "")
|
||||
rileyLinkServiceData.rileyLinkName = sp.getString(RileyLinkConst.Prefs.RileyLinkName, "")
|
||||
rfspy.startReader()
|
||||
medtronicUIComm = MedtronicUIComm(injector, aapsLogger, medtronicUtil, medtronicUIPostprocessor, medtronicCommunicationManager)
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly constructed")
|
||||
}
|
||||
|
||||
override fun getDeviceCommunicationManager(): MedtronicCommunicationManager {
|
||||
return medtronicCommunicationManager
|
||||
}
|
||||
|
||||
override fun setPumpDeviceState(pumpDeviceState: PumpDeviceState) {
|
||||
medtronicPumpStatus.pumpDeviceState = pumpDeviceState
|
||||
}
|
||||
|
||||
fun setPumpIDString(pumpID: String) {
|
||||
if (pumpID.length != 6) {
|
||||
aapsLogger.error("setPumpIDString: invalid pump id string: $pumpID")
|
||||
return
|
||||
}
|
||||
val pumpIDBytes = ByteUtil.fromHexString(pumpID)
|
||||
if (pumpIDBytes == null) {
|
||||
aapsLogger.error("Invalid pump ID? - PumpID is null.")
|
||||
rileyLinkServiceData.setPumpID("000000", byteArrayOf(0, 0, 0))
|
||||
} else if (pumpIDBytes.size != 3) {
|
||||
aapsLogger.error("Invalid pump ID? " + ByteUtil.shortHexString(pumpIDBytes))
|
||||
rileyLinkServiceData.setPumpID("000000", byteArrayOf(0, 0, 0))
|
||||
} else if (pumpID == "000000") {
|
||||
aapsLogger.error("Using pump ID $pumpID")
|
||||
rileyLinkServiceData.setPumpID(pumpID, byteArrayOf(0, 0, 0))
|
||||
} else {
|
||||
aapsLogger.info(LTag.PUMPBTCOMM, "Using pump ID $pumpID")
|
||||
val oldId = rileyLinkServiceData.pumpID
|
||||
rileyLinkServiceData.setPumpID(pumpID, pumpIDBytes)
|
||||
if (oldId != null && oldId != pumpID) {
|
||||
medtronicUtil.medtronicPumpModel = null // if we change pumpId, model probably changed too
|
||||
}
|
||||
return
|
||||
}
|
||||
medtronicPumpStatus.pumpDeviceState = PumpDeviceState.InvalidConfiguration
|
||||
|
||||
// LOG.info("setPumpIDString: saved pumpID " + idString);
|
||||
}
|
||||
|
||||
inner class LocalBinder : Binder() {
|
||||
val serviceInstance: RileyLinkMedtronicService
|
||||
get() = this@RileyLinkMedtronicService
|
||||
}
|
||||
|
||||
/* private functions */ // PumpInterface - REMOVE
|
||||
val isInitialized: Boolean
|
||||
get() = rileyLinkServiceData.rileyLinkServiceState.isReady
|
||||
|
||||
override fun verifyConfiguration(forceRileyLinkAddressRenewal: Boolean): Boolean {
|
||||
return try {
|
||||
val regexSN = "[0-9]{6}"
|
||||
val regexMac = "([\\da-fA-F]{1,2}(?::|$)){6}"
|
||||
medtronicPumpStatus.errorDescription = "-"
|
||||
val serialNr = sp.getStringOrNull(MedtronicConst.Prefs.PumpSerial, null)
|
||||
if (serialNr == null) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_serial_not_set)
|
||||
return false
|
||||
} else {
|
||||
if (!serialNr.matches(regexSN.toRegex())) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_serial_invalid)
|
||||
return false
|
||||
} else {
|
||||
if (serialNr != medtronicPumpStatus.serialNumber) {
|
||||
medtronicPumpStatus.serialNumber = serialNr
|
||||
serialChanged = true
|
||||
}
|
||||
}
|
||||
}
|
||||
val pumpTypePref = sp.getStringOrNull(MedtronicConst.Prefs.PumpType, null)
|
||||
if (pumpTypePref == null) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_pump_type_not_set)
|
||||
return false
|
||||
} else {
|
||||
val pumpTypePart = pumpTypePref.substring(0, 3)
|
||||
if (!pumpTypePart.matches("[0-9]{3}".toRegex())) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_pump_type_invalid)
|
||||
return false
|
||||
} else {
|
||||
val pumpType = medtronicPumpStatus.medtronicPumpMap[pumpTypePart]
|
||||
medtronicPumpStatus.medtronicDeviceType = medtronicPumpStatus.medtronicDeviceTypeMap[pumpTypePart]
|
||||
medtronicPumpPlugin.pumpType = pumpType
|
||||
if (pumpTypePart.startsWith("7")) medtronicPumpStatus.reservoirFullUnits = 300 else medtronicPumpStatus.reservoirFullUnits = 176
|
||||
}
|
||||
}
|
||||
val pumpFrequency = sp.getStringOrNull(MedtronicConst.Prefs.PumpFrequency, null)
|
||||
if (pumpFrequency == null) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_pump_frequency_not_set)
|
||||
return false
|
||||
} else {
|
||||
if (pumpFrequency != frequencies!![0] && pumpFrequency != frequencies!![1]) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_pump_frequency_invalid)
|
||||
return false
|
||||
} else {
|
||||
medtronicPumpStatus.pumpFrequency = pumpFrequency
|
||||
val isFrequencyUS = pumpFrequency == frequencies!![0]
|
||||
val newTargetFrequency = if (isFrequencyUS) //
|
||||
RileyLinkTargetFrequency.Medtronic_US else RileyLinkTargetFrequency.Medtronic_WorldWide
|
||||
if (rileyLinkServiceData.rileyLinkTargetFrequency != newTargetFrequency) {
|
||||
rileyLinkServiceData.rileyLinkTargetFrequency = newTargetFrequency
|
||||
}
|
||||
}
|
||||
}
|
||||
val rileyLinkAddress = sp.getStringOrNull(RileyLinkConst.Prefs.RileyLinkAddress, null)
|
||||
if (rileyLinkAddress == null) {
|
||||
aapsLogger.debug(LTag.PUMP, "RileyLink address invalid: null")
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_rileylink_address_invalid)
|
||||
return false
|
||||
} else {
|
||||
if (!rileyLinkAddress.matches(regexMac.toRegex())) {
|
||||
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_rileylink_address_invalid)
|
||||
aapsLogger.debug(LTag.PUMP, "RileyLink address invalid: %s", rileyLinkAddress)
|
||||
} else {
|
||||
if (rileyLinkAddress != this.rileyLinkAddress) {
|
||||
this.rileyLinkAddress = rileyLinkAddress
|
||||
rileyLinkAddressChanged = true
|
||||
}
|
||||
}
|
||||
}
|
||||
val maxBolusLcl = checkParameterValue(MedtronicConst.Prefs.MaxBolus, "25.0", 25.0)
|
||||
if (medtronicPumpStatus.maxBolus == null || medtronicPumpStatus.maxBolus != maxBolusLcl) {
|
||||
medtronicPumpStatus.maxBolus = maxBolusLcl
|
||||
|
||||
//LOG.debug("Max Bolus from AAPS settings is " + maxBolus);
|
||||
}
|
||||
val maxBasalLcl = checkParameterValue(MedtronicConst.Prefs.MaxBasal, "35.0", 35.0)
|
||||
if (medtronicPumpStatus.maxBasal == null || medtronicPumpStatus.maxBasal != maxBasalLcl) {
|
||||
medtronicPumpStatus.maxBasal = maxBasalLcl
|
||||
|
||||
//LOG.debug("Max Basal from AAPS settings is " + maxBasal);
|
||||
}
|
||||
val encodingTypeStr = sp.getStringOrNull(MedtronicConst.Prefs.Encoding, null)
|
||||
?: return false
|
||||
val newEncodingType = RileyLinkEncodingType.getByDescription(encodingTypeStr, resourceHelper)
|
||||
if (encodingType == null) {
|
||||
encodingType = newEncodingType
|
||||
} else if (encodingType != newEncodingType) {
|
||||
encodingType = newEncodingType
|
||||
encodingChanged = true
|
||||
}
|
||||
val batteryTypeStr = sp.getStringOrNull(MedtronicConst.Prefs.BatteryType, null)
|
||||
?: return false
|
||||
val batteryType = medtronicPumpStatus.getBatteryTypeByDescription(batteryTypeStr)
|
||||
if (medtronicPumpStatus.batteryType !== batteryType) {
|
||||
medtronicPumpStatus.batteryType = batteryType!!
|
||||
}
|
||||
|
||||
//String bolusDebugEnabled = sp.getStringOrNull(MedtronicConst.Prefs.BolusDebugEnabled, null);
|
||||
//boolean bolusDebug = bolusDebugEnabled != null && bolusDebugEnabled.equals(resourceHelper.gs(R.string.common_on));
|
||||
//MedtronicHistoryData.doubleBolusDebug = bolusDebug;
|
||||
rileyLinkServiceData.showBatteryLevel = sp.getBoolean(RileyLinkConst.Prefs.ShowBatteryLevel, false)
|
||||
reconfigureService(forceRileyLinkAddressRenewal)
|
||||
true
|
||||
} catch (ex: Exception) {
|
||||
medtronicPumpStatus.errorDescription = ex.message
|
||||
aapsLogger.error(LTag.PUMP, "Error on Verification: " + ex.message, ex)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun reconfigureService(forceRileyLinkAddressRenewal: Boolean): Boolean {
|
||||
if (!inPreInit) {
|
||||
if (serialChanged) {
|
||||
setPumpIDString(medtronicPumpStatus.serialNumber!!) // short operation
|
||||
serialChanged = false
|
||||
}
|
||||
if (rileyLinkAddressChanged || forceRileyLinkAddressRenewal) {
|
||||
rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.RileyLinkNewAddressSet, this)
|
||||
rileyLinkAddressChanged = false
|
||||
}
|
||||
if (encodingChanged) {
|
||||
changeRileyLinkEncoding(encodingType)
|
||||
encodingChanged = false
|
||||
}
|
||||
}
|
||||
|
||||
// if (targetFrequencyChanged && !inPreInit && MedtronicUtil.getMedtronicService() != null) {
|
||||
// RileyLinkUtil.setRileyLinkTargetFrequency(targetFrequency);
|
||||
// // RileyLinkUtil.getRileyLinkCommunicationManager().refreshRileyLinkTargetFrequency();
|
||||
// targetFrequencyChanged = false;
|
||||
// }
|
||||
return !rileyLinkAddressChanged && !serialChanged && !encodingChanged // && !targetFrequencyChanged);
|
||||
}
|
||||
|
||||
private fun checkParameterValue(key: Int, defaultValue: String, defaultValueDouble: Double): Double {
|
||||
var `val`: Double
|
||||
val value = sp.getString(key, defaultValue)
|
||||
`val` = try {
|
||||
value.toDouble()
|
||||
} catch (ex: Exception) {
|
||||
aapsLogger.error("Error parsing setting: %s, value found %s", key, value)
|
||||
defaultValueDouble
|
||||
}
|
||||
if (`val` > defaultValueDouble) {
|
||||
sp.putString(key, defaultValue)
|
||||
`val` = defaultValueDouble
|
||||
}
|
||||
return `val`
|
||||
}
|
||||
|
||||
fun setNotInPreInit(): Boolean {
|
||||
inPreInit = false
|
||||
return reconfigureService(false)
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.util;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.R;
|
||||
|
||||
/**
|
||||
* Created by andy on 5/12/18.
|
||||
*/
|
||||
|
||||
public class MedtronicConst {
|
||||
|
||||
static final String Prefix = "AAPS.Medtronic.";
|
||||
|
||||
public static class Prefs {
|
||||
public static final int PumpSerial = R.string.key_medtronic_serial;
|
||||
public static final int PumpType = R.string.key_medtronic_pump_type;
|
||||
public static final int PumpFrequency = R.string.key_medtronic_frequency;
|
||||
public static final int MaxBolus = R.string.key_medtronic_max_bolus;
|
||||
public static final int MaxBasal = R.string.key_medtronic_max_basal;
|
||||
public static final int BolusDelay = R.string.key_medtronic_bolus_delay;
|
||||
public static final int Encoding = R.string.key_medtronic_encoding;
|
||||
public static final int BatteryType = R.string.key_medtronic_battery_type;
|
||||
public static final int BolusDebugEnabled = R.string.key_medtronic_bolus_debug;
|
||||
}
|
||||
|
||||
public static class Statistics {
|
||||
|
||||
public static final String StatsPrefix = "medtronic_";
|
||||
public static final String FirstPumpStart = Prefix + "first_pump_use";
|
||||
public static final String LastGoodPumpCommunicationTime = Prefix + "lastGoodPumpCommunicationTime";
|
||||
public static final String LastGoodPumpFrequency = Prefix + "LastGoodPumpFrequency";
|
||||
public static final String TBRsSet = StatsPrefix + "tbrs_set";
|
||||
public static final String StandardBoluses = StatsPrefix + "std_boluses_delivered";
|
||||
public static final String SMBBoluses = StatsPrefix + "smb_boluses_delivered";
|
||||
public static final String LastPumpHistoryEntry = StatsPrefix + "pump_history_entry";
|
||||
public static final String LastPrime = StatsPrefix + "last_sent_prime";
|
||||
public static final String LastRewind = StatsPrefix + "last_sent_rewind";
|
||||
public static final String InternalTemporaryDatabase = StatsPrefix + "temporary_entries";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.util
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.R
|
||||
|
||||
/**
|
||||
* Created by andy on 5/12/18.
|
||||
*/
|
||||
object MedtronicConst {
|
||||
|
||||
const val Prefix = "AAPS.Medtronic."
|
||||
|
||||
object Prefs {
|
||||
@JvmField val PumpSerial = R.string.key_medtronic_serial
|
||||
@JvmField val PumpType = R.string.key_medtronic_pump_type
|
||||
@JvmField val PumpFrequency = R.string.key_medtronic_frequency
|
||||
@JvmField val MaxBolus = R.string.key_medtronic_max_bolus
|
||||
@JvmField val MaxBasal = R.string.key_medtronic_max_basal
|
||||
@JvmField val BolusDelay = R.string.key_medtronic_bolus_delay
|
||||
@JvmField val Encoding = R.string.key_medtronic_encoding
|
||||
@JvmField val BatteryType = R.string.key_medtronic_battery_type
|
||||
val BolusDebugEnabled = R.string.key_medtronic_bolus_debug
|
||||
}
|
||||
|
||||
object Statistics {
|
||||
const val StatsPrefix = "medtronic_"
|
||||
const val FirstPumpStart = Prefix + "first_pump_use"
|
||||
const val LastGoodPumpCommunicationTime = Prefix + "lastGoodPumpCommunicationTime"
|
||||
const val LastGoodPumpFrequency = Prefix + "LastGoodPumpFrequency"
|
||||
const val TBRsSet = StatsPrefix + "tbrs_set"
|
||||
const val StandardBoluses = StatsPrefix + "std_boluses_delivered"
|
||||
const val SMBBoluses = StatsPrefix + "smb_boluses_delivered"
|
||||
const val LastPumpHistoryEntry = StatsPrefix + "pump_history_entry"
|
||||
const val LastPrime = StatsPrefix + "last_sent_prime"
|
||||
const val LastRewind = StatsPrefix + "last_sent_rewind"
|
||||
const val InternalTemporaryDatabase = StatsPrefix + "temporary_entries"
|
||||
}
|
||||
}
|
|
@ -1,456 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.util;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import org.joda.time.LocalTime;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.ClockDTO;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.PumpSettingDTO;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.RLHistoryItemMedtronic;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicNotificationType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
|
||||
/**
|
||||
* Created by andy on 5/9/18.
|
||||
*/
|
||||
|
||||
@Singleton
|
||||
public class MedtronicUtil {
|
||||
|
||||
private final int ENVELOPE_SIZE = 4; // 0xA7 S1 S2 S3 CMD PARAM_COUNT [PARAMS]
|
||||
private static final boolean lowLevelDebug = true;
|
||||
//private MedtronicDeviceType medtronicPumpModel;
|
||||
private MedtronicCommandType currentCommand;
|
||||
private Map<String, PumpSettingDTO> settings;
|
||||
private final int BIG_FRAME_LENGTH = 65;
|
||||
private final int doneBit = 1 << 7;
|
||||
private ClockDTO pumpTime;
|
||||
public Gson gsonInstance = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
|
||||
|
||||
private final AAPSLogger aapsLogger;
|
||||
private final RxBusWrapper rxBus;
|
||||
private final RileyLinkUtil rileyLinkUtil;
|
||||
private final MedtronicPumpStatus medtronicPumpStatus;
|
||||
|
||||
@Inject
|
||||
public MedtronicUtil(
|
||||
AAPSLogger aapsLogger,
|
||||
RxBusWrapper rxBus,
|
||||
RileyLinkUtil rileyLinkUtil,
|
||||
MedtronicPumpStatus medtronicPumpStatus
|
||||
) {
|
||||
this.aapsLogger = aapsLogger;
|
||||
this.rxBus = rxBus;
|
||||
this.rileyLinkUtil = rileyLinkUtil;
|
||||
this.medtronicPumpStatus = medtronicPumpStatus;
|
||||
}
|
||||
|
||||
public LocalTime getTimeFrom30MinInterval(int interval) {
|
||||
if (interval % 2 == 0) {
|
||||
return new LocalTime(interval / 2, 0);
|
||||
} else {
|
||||
return new LocalTime((interval - 1) / 2, 30);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int getIntervalFromMinutes(int minutes) {
|
||||
return minutes / 30;
|
||||
}
|
||||
|
||||
|
||||
public static int makeUnsignedShort(int b2, int b1) {
|
||||
int k = (b2 & 0xff) << 8 | b1 & 0xff;
|
||||
return k;
|
||||
}
|
||||
|
||||
public static byte[] getByteArrayFromUnsignedShort(int shortValue, boolean returnFixedSize) {
|
||||
byte highByte = (byte) (shortValue >> 8 & 0xFF);
|
||||
byte lowByte = (byte) (shortValue & 0xFF);
|
||||
|
||||
if (highByte > 0) {
|
||||
return createByteArray(highByte, lowByte);
|
||||
} else {
|
||||
return returnFixedSize ? createByteArray(highByte, lowByte) : createByteArray(lowByte);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static byte[] createByteArray(byte... data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public static byte[] createByteArray(List<Byte> data) {
|
||||
|
||||
byte[] array = new byte[data.size()];
|
||||
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
array[i] = data.get(i);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
public double decodeBasalInsulin(int i, int j) {
|
||||
return decodeBasalInsulin(makeUnsignedShort(i, j));
|
||||
}
|
||||
|
||||
|
||||
public double decodeBasalInsulin(int i) {
|
||||
return (double) i / 40.0d;
|
||||
}
|
||||
|
||||
|
||||
public byte[] getBasalStrokes(double amount) {
|
||||
return getBasalStrokes(amount, false);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] getBasalStrokes(double amount, boolean returnFixedSize) {
|
||||
return getStrokes(amount, 40, returnFixedSize);
|
||||
}
|
||||
|
||||
|
||||
public int getBasalStrokesInt(double amount) {
|
||||
return getStrokesInt(amount, 40);
|
||||
}
|
||||
|
||||
|
||||
public byte[] getBolusStrokes(double amount) {
|
||||
|
||||
int strokesPerUnit = medtronicPumpStatus.medtronicDeviceType.getBolusStrokes();
|
||||
|
||||
int length;
|
||||
int scrollRate;
|
||||
|
||||
if (strokesPerUnit >= 40) {
|
||||
length = 2;
|
||||
|
||||
// 40-stroke pumps scroll faster for higher unit values
|
||||
|
||||
if (amount > 10)
|
||||
scrollRate = 4;
|
||||
else if (amount > 1)
|
||||
scrollRate = 2;
|
||||
else
|
||||
scrollRate = 1;
|
||||
|
||||
} else {
|
||||
length = 1;
|
||||
scrollRate = 1;
|
||||
}
|
||||
|
||||
int strokes = (int) (amount * ((strokesPerUnit * 1.0d) / (scrollRate * 1.0d))) * scrollRate;
|
||||
|
||||
byte[] body = ByteUtil.fromHexString(String.format("%02x%0" + (2 * length) + "x", length, strokes));
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
|
||||
public byte[] createCommandBody(byte[] input) {
|
||||
|
||||
return ByteUtil.concat((byte) input.length, input);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] getStrokes(double amount, int strokesPerUnit, boolean returnFixedSize) {
|
||||
|
||||
int strokes = getStrokesInt(amount, strokesPerUnit);
|
||||
|
||||
return getByteArrayFromUnsignedShort(strokes, returnFixedSize);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static int getStrokesInt(double amount, int strokesPerUnit) {
|
||||
|
||||
int length = 1;
|
||||
int scrollRate = 1;
|
||||
|
||||
if (strokesPerUnit >= 40) {
|
||||
length = 2;
|
||||
|
||||
// 40-stroke pumps scroll faster for higher unit values
|
||||
if (amount > 10)
|
||||
scrollRate = 4;
|
||||
else if (amount > 1)
|
||||
scrollRate = 2;
|
||||
}
|
||||
|
||||
int strokes = (int) (amount * (strokesPerUnit / (scrollRate * 1.0d)));
|
||||
|
||||
strokes *= scrollRate;
|
||||
|
||||
return strokes;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void sendNotification(MedtronicNotificationType notificationType, ResourceHelper resourceHelper, RxBusWrapper rxBus) {
|
||||
Notification notification = new Notification( //
|
||||
notificationType.getNotificationType(), //
|
||||
resourceHelper.gs(notificationType.getResourceId()), //
|
||||
notificationType.getNotificationUrgency());
|
||||
rxBus.send(new EventNewNotification(notification));
|
||||
}
|
||||
|
||||
|
||||
public void sendNotification(MedtronicNotificationType notificationType, ResourceHelper resourceHelper, RxBusWrapper rxBus, Object... parameters) {
|
||||
Notification notification = new Notification( //
|
||||
notificationType.getNotificationType(), //
|
||||
resourceHelper.gs(notificationType.getResourceId(), parameters), //
|
||||
notificationType.getNotificationUrgency());
|
||||
rxBus.send(new EventNewNotification(notification));
|
||||
}
|
||||
|
||||
|
||||
public void dismissNotification(MedtronicNotificationType notificationType, RxBusWrapper rxBus) {
|
||||
rxBus.send(new EventDismissNotification(notificationType.getNotificationType()));
|
||||
}
|
||||
|
||||
|
||||
// public byte[] buildCommandPayload(MessageType commandType, byte[] parameters) {
|
||||
// return buildCommandPayload(commandType.getValue(), parameters);
|
||||
// }
|
||||
|
||||
|
||||
public byte[] buildCommandPayload(RileyLinkServiceData rileyLinkServiceData, MedtronicCommandType commandType, byte[] parameters) {
|
||||
return buildCommandPayload(rileyLinkServiceData, commandType.commandCode, parameters);
|
||||
}
|
||||
|
||||
|
||||
public byte[] buildCommandPayload(RileyLinkServiceData rileyLinkServiceData, byte commandType, byte[] parameters) {
|
||||
// A7 31 65 51 C0 00 52
|
||||
|
||||
byte commandLength = (byte) (parameters == null ? 2 : 2 + parameters.length);
|
||||
|
||||
ByteBuffer sendPayloadBuffer = ByteBuffer.allocate(ENVELOPE_SIZE + commandLength); // + CRC_SIZE
|
||||
sendPayloadBuffer.order(ByteOrder.BIG_ENDIAN);
|
||||
|
||||
byte[] serialNumberBCD = rileyLinkServiceData.pumpIDBytes;
|
||||
|
||||
sendPayloadBuffer.put((byte) 0xA7);
|
||||
sendPayloadBuffer.put(serialNumberBCD[0]);
|
||||
sendPayloadBuffer.put(serialNumberBCD[1]);
|
||||
sendPayloadBuffer.put(serialNumberBCD[2]);
|
||||
|
||||
sendPayloadBuffer.put(commandType);
|
||||
|
||||
if (parameters == null) {
|
||||
sendPayloadBuffer.put((byte) 0x00);
|
||||
} else {
|
||||
sendPayloadBuffer.put((byte) parameters.length); // size
|
||||
|
||||
for (byte val : parameters) {
|
||||
sendPayloadBuffer.put(val);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] payload = sendPayloadBuffer.array();
|
||||
|
||||
aapsLogger.debug(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "buildCommandPayload [%s]", ByteUtil.shortHexString(payload)));
|
||||
|
||||
// int crc = computeCRC8WithPolynomial(payload, 0, payload.length - 1);
|
||||
|
||||
// LOG.info("crc: " + crc);
|
||||
|
||||
// sendPayloadBuffer.put((byte) crc);
|
||||
|
||||
return sendPayloadBuffer.array();
|
||||
}
|
||||
|
||||
|
||||
// Note: at the moment supported only for 24 items, if you will use it for more than
|
||||
// that you will need to add
|
||||
public List<List<Byte>> getBasalProfileFrames(byte[] data) {
|
||||
|
||||
boolean done = false;
|
||||
int start = 0;
|
||||
int frame = 1;
|
||||
|
||||
List<List<Byte>> frames = new ArrayList<>();
|
||||
boolean lastFrame = false;
|
||||
|
||||
do {
|
||||
int frameLength = BIG_FRAME_LENGTH - 1;
|
||||
|
||||
if (start + frameLength > data.length) {
|
||||
frameLength = data.length - start;
|
||||
}
|
||||
|
||||
// System.out.println("Framelength: " + frameLength);
|
||||
|
||||
byte[] substring = ByteUtil.substring(data, start, frameLength);
|
||||
|
||||
// System.out.println("Subarray: " + ByteUtil.getCompactString(substring));
|
||||
// System.out.println("Subarray Lenths: " + substring.length);
|
||||
|
||||
List<Byte> frameData = ByteUtil.getListFromByteArray(substring);
|
||||
|
||||
if (isEmptyFrame(frameData)) {
|
||||
byte b = (byte) frame;
|
||||
// b |= 0x80;
|
||||
b |= 0b1000_0000;
|
||||
// b |= doneBit;
|
||||
|
||||
frameData.add(0, b);
|
||||
|
||||
checkAndAppenLastFrame(frameData);
|
||||
|
||||
lastFrame = true;
|
||||
|
||||
done = true;
|
||||
} else {
|
||||
frameData.add(0, (byte) frame);
|
||||
}
|
||||
|
||||
// System.out.println("Subarray: " + ByteUtil.getCompactString(substring));
|
||||
|
||||
frames.add(frameData);
|
||||
|
||||
frame++;
|
||||
start += (BIG_FRAME_LENGTH - 1);
|
||||
|
||||
if (start == data.length) {
|
||||
done = true;
|
||||
}
|
||||
|
||||
} while (!done);
|
||||
|
||||
if (!lastFrame) {
|
||||
List<Byte> frameData = new ArrayList<>();
|
||||
|
||||
byte b = (byte) frame;
|
||||
b |= 0b1000_0000;
|
||||
// b |= doneBit;
|
||||
|
||||
frameData.add(b);
|
||||
|
||||
checkAndAppenLastFrame(frameData);
|
||||
}
|
||||
|
||||
return frames;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void checkAndAppenLastFrame(List<Byte> frameData) {
|
||||
|
||||
if (frameData.size() == BIG_FRAME_LENGTH)
|
||||
return;
|
||||
|
||||
int missing = BIG_FRAME_LENGTH - frameData.size();
|
||||
|
||||
for (int i = 0; i < missing; i++) {
|
||||
frameData.add((byte) 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean isEmptyFrame(List<Byte> frameData) {
|
||||
|
||||
for (Byte frameDateEntry : frameData) {
|
||||
if (frameDateEntry != 0x00) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isLowLevelDebug() {
|
||||
return lowLevelDebug;
|
||||
}
|
||||
|
||||
public boolean isModelSet() {
|
||||
return medtronicPumpStatus.medtronicDeviceType != null;
|
||||
}
|
||||
|
||||
public MedtronicDeviceType getMedtronicPumpModel() {
|
||||
return medtronicPumpStatus.medtronicDeviceType;
|
||||
}
|
||||
|
||||
public void setMedtronicPumpModel(MedtronicDeviceType medtronicPumpModel) {
|
||||
this.medtronicPumpStatus.medtronicDeviceType = medtronicPumpModel;
|
||||
}
|
||||
|
||||
public MedtronicCommandType getCurrentCommand() {
|
||||
return this.currentCommand;
|
||||
}
|
||||
|
||||
public void setCurrentCommand(MedtronicCommandType currentCommand) {
|
||||
this.currentCommand = currentCommand;
|
||||
|
||||
if (currentCommand != null)
|
||||
rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItemMedtronic(currentCommand));
|
||||
|
||||
}
|
||||
|
||||
public int pageNumber;
|
||||
public Integer frameNumber;
|
||||
|
||||
|
||||
public void setCurrentCommand(MedtronicCommandType currentCommand, int pageNumber_, Integer frameNumber_) {
|
||||
pageNumber = pageNumber_;
|
||||
frameNumber = frameNumber_;
|
||||
|
||||
if (this.currentCommand != currentCommand) {
|
||||
setCurrentCommand(currentCommand);
|
||||
}
|
||||
|
||||
rxBus.send(new EventRileyLinkDeviceStatusChange(medtronicPumpStatus.getPumpDeviceState()));
|
||||
}
|
||||
|
||||
|
||||
public static boolean isSame(Double d1, Double d2) {
|
||||
double diff = d1 - d2;
|
||||
|
||||
return (Math.abs(diff) <= 0.000001);
|
||||
}
|
||||
|
||||
|
||||
public Map<String, PumpSettingDTO> getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public void setSettings(Map<String, PumpSettingDTO> settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public void setPumpTime(ClockDTO pumpTime) {
|
||||
this.pumpTime = pumpTime;
|
||||
}
|
||||
|
||||
public ClockDTO getPumpTime() {
|
||||
return this.pumpTime;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,314 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.util
|
||||
|
||||
import com.google.gson.GsonBuilder
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.ClockDTO
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.PumpSettingDTO
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.RLHistoryItemMedtronic
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicNotificationType
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import org.joda.time.LocalTime
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.experimental.or
|
||||
|
||||
/**
|
||||
* Created by andy on 5/9/18.
|
||||
*/
|
||||
@Singleton
|
||||
class MedtronicUtil @Inject constructor(
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val rxBus: RxBusWrapper,
|
||||
private val rileyLinkUtil: RileyLinkUtil,
|
||||
private val medtronicPumpStatus: MedtronicPumpStatus
|
||||
) {
|
||||
|
||||
private val ENVELOPE_SIZE = 4 // 0xA7 S1 S2 S3 CMD PARAM_COUNT [PARAMS]
|
||||
|
||||
//private MedtronicDeviceType medtronicPumpModel;
|
||||
private var currentCommand: MedtronicCommandType? = null
|
||||
var settings: Map<String, PumpSettingDTO>? = null
|
||||
private val BIG_FRAME_LENGTH = 65
|
||||
private val doneBit = 1 shl 7
|
||||
var pumpTime: ClockDTO? = null
|
||||
var gsonInstance = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
|
||||
|
||||
|
||||
fun getTimeFrom30MinInterval(interval: Int): LocalTime {
|
||||
return if (interval % 2 == 0) {
|
||||
LocalTime(interval / 2, 0)
|
||||
} else {
|
||||
LocalTime((interval - 1) / 2, 30)
|
||||
}
|
||||
}
|
||||
|
||||
fun decodeBasalInsulin(i: Int, j: Int): Double {
|
||||
return decodeBasalInsulin(makeUnsignedShort(i, j))
|
||||
}
|
||||
|
||||
fun decodeBasalInsulin(i: Int): Double {
|
||||
return i.toDouble() / 40.0
|
||||
}
|
||||
|
||||
fun getBasalStrokes(amount: Double): ByteArray {
|
||||
return getBasalStrokes(amount, false)
|
||||
}
|
||||
|
||||
fun getBasalStrokesInt(amount: Double): Int {
|
||||
return getStrokesInt(amount, 40)
|
||||
}
|
||||
|
||||
fun getBolusStrokes(amount: Double): ByteArray {
|
||||
val strokesPerUnit = medtronicPumpStatus.medtronicDeviceType!!.bolusStrokes
|
||||
val length: Int
|
||||
val scrollRate: Int
|
||||
if (strokesPerUnit >= 40) {
|
||||
length = 2
|
||||
|
||||
// 40-stroke pumps scroll faster for higher unit values
|
||||
scrollRate = if (amount > 10) 4 else if (amount > 1) 2 else 1
|
||||
} else {
|
||||
length = 1
|
||||
scrollRate = 1
|
||||
}
|
||||
val strokes = (amount * (strokesPerUnit * 1.0 / (scrollRate * 1.0))).toInt() * scrollRate
|
||||
return ByteUtil.fromHexString(String.format("%02x%0" + 2 * length + "x", length, strokes))
|
||||
}
|
||||
|
||||
fun createCommandBody(input: ByteArray): ByteArray {
|
||||
return ByteUtil.concat(input.size.toByte(), input)
|
||||
}
|
||||
|
||||
fun sendNotification(notificationType: MedtronicNotificationType, resourceHelper: ResourceHelper, rxBus: RxBusWrapper) {
|
||||
val notification = Notification( //
|
||||
notificationType.notificationType, //
|
||||
resourceHelper.gs(notificationType.resourceId), //
|
||||
notificationType.notificationUrgency)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
}
|
||||
|
||||
fun sendNotification(notificationType: MedtronicNotificationType, resourceHelper: ResourceHelper, rxBus: RxBusWrapper, vararg parameters: Any?) {
|
||||
val notification = Notification( //
|
||||
notificationType.notificationType, //
|
||||
resourceHelper.gs(notificationType.resourceId, *parameters), //
|
||||
notificationType.notificationUrgency)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
}
|
||||
|
||||
fun dismissNotification(notificationType: MedtronicNotificationType, rxBus: RxBusWrapper) {
|
||||
rxBus.send(EventDismissNotification(notificationType.notificationType))
|
||||
}
|
||||
|
||||
fun buildCommandPayload(rileyLinkServiceData: RileyLinkServiceData, commandType: MedtronicCommandType, parameters: ByteArray?): ByteArray {
|
||||
return buildCommandPayload(rileyLinkServiceData, commandType.commandCode, parameters)
|
||||
}
|
||||
|
||||
fun buildCommandPayload(rileyLinkServiceData: RileyLinkServiceData, commandType: Byte, parameters: ByteArray?): ByteArray {
|
||||
// A7 31 65 51 C0 00 52
|
||||
val commandLength = (if (parameters == null) 2 else 2 + parameters.size).toByte()
|
||||
val sendPayloadBuffer = ByteBuffer.allocate(ENVELOPE_SIZE + commandLength) // + CRC_SIZE
|
||||
sendPayloadBuffer.order(ByteOrder.BIG_ENDIAN)
|
||||
val serialNumberBCD = rileyLinkServiceData.pumpIDBytes
|
||||
sendPayloadBuffer.put(0xA7.toByte())
|
||||
sendPayloadBuffer.put(serialNumberBCD[0])
|
||||
sendPayloadBuffer.put(serialNumberBCD[1])
|
||||
sendPayloadBuffer.put(serialNumberBCD[2])
|
||||
sendPayloadBuffer.put(commandType)
|
||||
if (parameters == null) {
|
||||
sendPayloadBuffer.put(0x00.toByte())
|
||||
} else {
|
||||
sendPayloadBuffer.put(parameters.size.toByte()) // size
|
||||
for (`val` in parameters) {
|
||||
sendPayloadBuffer.put(`val`)
|
||||
}
|
||||
}
|
||||
val payload = sendPayloadBuffer.array()
|
||||
aapsLogger.debug(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "buildCommandPayload [%s]", ByteUtil.shortHexString(payload)))
|
||||
|
||||
// int crc = computeCRC8WithPolynomial(payload, 0, payload.length - 1);
|
||||
|
||||
// LOG.info("crc: " + crc);
|
||||
|
||||
// sendPayloadBuffer.put((byte) crc);
|
||||
return sendPayloadBuffer.array()
|
||||
}
|
||||
|
||||
// Note: at the moment supported only for 24 items, if you will use it for more than
|
||||
// that you will need to add
|
||||
fun getBasalProfileFrames(data: ByteArray): List<List<Byte>> {
|
||||
var done = false
|
||||
var start = 0
|
||||
var frame = 1
|
||||
val frames: MutableList<List<Byte>> = ArrayList()
|
||||
var lastFrame = false
|
||||
do {
|
||||
var frameLength = BIG_FRAME_LENGTH - 1
|
||||
if (start + frameLength > data.size) {
|
||||
frameLength = data.size - start
|
||||
}
|
||||
|
||||
// System.out.println("Framelength: " + frameLength);
|
||||
val substring = ByteUtil.substring(data, start, frameLength)
|
||||
|
||||
// System.out.println("Subarray: " + ByteUtil.getCompactString(substring));
|
||||
// System.out.println("Subarray Lenths: " + substring.length);
|
||||
val frameData = ByteUtil.getListFromByteArray(substring)
|
||||
if (isEmptyFrame(frameData)) {
|
||||
var b = frame.toByte()
|
||||
// b |= 0x80;
|
||||
b = b or 128.toByte()
|
||||
// b |= doneBit;
|
||||
frameData.add(0, b)
|
||||
checkAndAppenLastFrame(frameData)
|
||||
lastFrame = true
|
||||
done = true
|
||||
} else {
|
||||
frameData.add(0, frame.toByte())
|
||||
}
|
||||
|
||||
// System.out.println("Subarray: " + ByteUtil.getCompactString(substring));
|
||||
frames.add(frameData)
|
||||
frame++
|
||||
start += BIG_FRAME_LENGTH - 1
|
||||
if (start == data.size) {
|
||||
done = true
|
||||
}
|
||||
} while (!done)
|
||||
if (!lastFrame) {
|
||||
val frameData: MutableList<Byte> = ArrayList()
|
||||
var b = frame.toByte()
|
||||
b = b or 128.toByte()
|
||||
// b |= doneBit;
|
||||
frameData.add(b)
|
||||
checkAndAppenLastFrame(frameData)
|
||||
}
|
||||
return frames
|
||||
}
|
||||
|
||||
private fun checkAndAppenLastFrame(frameData: MutableList<Byte>) {
|
||||
if (frameData.size == BIG_FRAME_LENGTH) return
|
||||
val missing = BIG_FRAME_LENGTH - frameData.size
|
||||
for (i in 0 until missing) {
|
||||
frameData.add(0x00.toByte())
|
||||
}
|
||||
}
|
||||
|
||||
private fun isEmptyFrame(frameData: List<Byte>): Boolean {
|
||||
for (frameDateEntry in frameData) {
|
||||
if (frameDateEntry.toInt() != 0x00) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
val isModelSet: Boolean
|
||||
get() = medtronicPumpStatus.medtronicDeviceType != null
|
||||
|
||||
var medtronicPumpModel: MedtronicDeviceType?
|
||||
get() = medtronicPumpStatus.medtronicDeviceType
|
||||
set(medtronicPumpModel) {
|
||||
medtronicPumpStatus.medtronicDeviceType = medtronicPumpModel
|
||||
}
|
||||
|
||||
fun getCurrentCommand(): MedtronicCommandType? {
|
||||
return currentCommand
|
||||
}
|
||||
|
||||
fun setCurrentCommand(currentCommandIn: MedtronicCommandType?) {
|
||||
this.currentCommand = currentCommandIn
|
||||
if (currentCommand != null) rileyLinkUtil.rileyLinkHistory.add(RLHistoryItemMedtronic(currentCommandIn!!))
|
||||
}
|
||||
|
||||
var pageNumber = 0
|
||||
var frameNumber: Int? = null
|
||||
|
||||
fun setCurrentCommand(currentCommand: MedtronicCommandType, pageNumber_: Int, frameNumber_: Int?) {
|
||||
pageNumber = pageNumber_
|
||||
frameNumber = frameNumber_
|
||||
if (this.currentCommand !== currentCommand) {
|
||||
setCurrentCommand(currentCommand)
|
||||
}
|
||||
rxBus.send(EventRileyLinkDeviceStatusChange(medtronicPumpStatus.pumpDeviceState))
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val isLowLevelDebug = true
|
||||
fun getIntervalFromMinutes(minutes: Int): Int {
|
||||
return minutes / 30
|
||||
}
|
||||
|
||||
fun makeUnsignedShort(b2: Int, b1: Int): Int {
|
||||
return b2 and 0xff shl 8 or b1 and 0xff
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getByteArrayFromUnsignedShort(shortValue: Int, returnFixedSize: Boolean): ByteArray {
|
||||
val highByte = (shortValue shr 8 and 0xFF).toByte()
|
||||
val lowByte = (shortValue and 0xFF).toByte()
|
||||
return if (highByte > 0) {
|
||||
createByteArray(highByte, lowByte)
|
||||
} else {
|
||||
if (returnFixedSize) createByteArray(highByte, lowByte) else createByteArray(lowByte)
|
||||
}
|
||||
}
|
||||
|
||||
fun createByteArray(vararg data: Byte): ByteArray {
|
||||
return data
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createByteArray(data: List<Byte>): ByteArray {
|
||||
val array = ByteArray(data.size)
|
||||
for (i in data.indices) {
|
||||
array[i] = data[i]
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
fun getBasalStrokes(amount: Double, returnFixedSize: Boolean): ByteArray {
|
||||
return getStrokes(amount, 40, returnFixedSize)
|
||||
}
|
||||
|
||||
fun getStrokes(amount: Double, strokesPerUnit: Int, returnFixedSize: Boolean): ByteArray {
|
||||
val strokes = getStrokesInt(amount, strokesPerUnit)
|
||||
return getByteArrayFromUnsignedShort(strokes, returnFixedSize)
|
||||
}
|
||||
|
||||
fun getStrokesInt(amount: Double, strokesPerUnit: Int): Int {
|
||||
var length = 1
|
||||
var scrollRate = 1
|
||||
if (strokesPerUnit >= 40) {
|
||||
length = 2
|
||||
|
||||
// 40-stroke pumps scroll faster for higher unit values
|
||||
if (amount > 10) scrollRate = 4 else if (amount > 1) scrollRate = 2
|
||||
}
|
||||
var strokes = (amount * (strokesPerUnit / (scrollRate * 1.0))).toInt()
|
||||
strokes *= scrollRate
|
||||
return strokes
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isSame(d1: Double, d2: Double): Boolean {
|
||||
val diff = d1 - d2
|
||||
return Math.abs(diff) <= 0.000001
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -95,6 +95,9 @@
|
|||
<string name="medtronic_cmd_desc_get_history">Get History - Page %1$d (%2$d/16)</string>
|
||||
<string name="medtronic_cmd_desc_get_history_request">Get History - Page %1$d</string>
|
||||
<string name="medtronic_cmd_desc_get_time">Get Pump Time</string>
|
||||
<string name="medtronic_cmd_desc_set_time">Set Pump Time</string>
|
||||
<string name="medtronic_cmd_desc_get_battery_status">Get Battery Status</string>
|
||||
|
||||
<string name="medtronic_cmd_desc_get_settings">Get Settings</string>
|
||||
<string name="medtronic_cmd_desc_get_model">Get Pump Model</string>
|
||||
<string name="medtronic_cmd_desc_get_basal_profile">Get Basal Profile</string>
|
||||
|
@ -115,8 +118,7 @@
|
|||
<string name="key_set_neutral_temps" translatable="false">set_neutral_temps</string>
|
||||
<string name="set_neutral_temps_title">Set neutral temp basals</string>
|
||||
<string name="set_neutral_temps_summary">If enabled, it will cancel a temporary basal before the end of each hour. This method can help stop some pumps beeping/vibrating on the hour.</string>
|
||||
|
||||
|
||||
<string name="mdt_tbr_remaining">%1$.1f U/h (%2$d min remaining)</string>
|
||||
<string name="sixdigitnumber" translatable="false">^\\d{6}</string>
|
||||
|
||||
</resources>
|
|
@ -186,22 +186,6 @@ public class ByteUtil {
|
|||
}
|
||||
|
||||
|
||||
// public static byte[] fromByteList(List<Byte> byteArray) {
|
||||
// byte[] rval = new byte[byteArray.size()];
|
||||
// for (int i = 0; i < byteArray.size(); i++) {
|
||||
// rval[i] = byteArray.get(i);
|
||||
// }
|
||||
// return rval;
|
||||
// }
|
||||
|
||||
// public static List<Byte> toByteList(byte[] data) {
|
||||
// ArrayList<Byte> rval = new ArrayList<>(data.length);
|
||||
// for (int i = 0; i < data.length; i++) {
|
||||
// rval.add(i, new Byte(data[i]));
|
||||
// }
|
||||
// return rval;
|
||||
// }
|
||||
|
||||
public static List<Byte> getListFromByteArray(byte[] array) {
|
||||
List<Byte> listOut = new ArrayList<Byte>();
|
||||
|
||||
|
@ -340,6 +324,9 @@ public class ByteUtil {
|
|||
return toInt(b1, b2, b3, null, BitConversion.BIG_ENDIAN);
|
||||
}
|
||||
|
||||
public static int toInt(Byte b1, Byte b2, Byte b3) {
|
||||
return toInt(b1, b2, b3, null, BitConversion.BIG_ENDIAN);
|
||||
}
|
||||
|
||||
public static int toInt(int b1, int b2, BitConversion flag) {
|
||||
return toInt(b1, b2, null, null, flag);
|
||||
|
|
Loading…
Reference in a new issue