- 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
|
package info.nightscout.androidaps.plugins.general.actions.defs
|
||||||
|
|
||||||
interface CustomActionType {
|
interface CustomActionType {
|
||||||
val key: String?
|
fun getKey(): String
|
||||||
}
|
}
|
|
@ -244,7 +244,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
||||||
|
|
||||||
public long lastDataTime() {
|
public long lastDataTime() {
|
||||||
aapsLogger.debug(LTag.PUMP, "lastDataTime [PumpPluginAbstract].");
|
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
|
// Pump capabilities
|
||||||
|
|
||||||
@NonNull public PumpDescription getPumpDescription() {
|
|
||||||
|
public PumpDescription getPumpDescription() {
|
||||||
return pumpDescription;
|
return pumpDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +332,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public JSONObject getJSONStatus(@NonNull Profile profile, @NonNull String profileName, @NonNull String version) {
|
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();
|
return new JSONObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,8 +342,8 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
||||||
JSONObject status = new JSONObject();
|
JSONObject status = new JSONObject();
|
||||||
JSONObject extended = new JSONObject();
|
JSONObject extended = new JSONObject();
|
||||||
try {
|
try {
|
||||||
battery.put("percent", getPumpStatusData().batteryRemaining);
|
battery.put("percent", getPumpStatusData().getBatteryRemaining());
|
||||||
status.put("status", getPumpStatusData().pumpStatusType != null ? getPumpStatusData().pumpStatusType.getStatus() : "normal");
|
status.put("status", getPumpStatusData().getPumpStatusType() != null ? getPumpStatusData().getPumpStatusType().getStatus() : "normal");
|
||||||
extended.put("Version", version);
|
extended.put("Version", version);
|
||||||
try {
|
try {
|
||||||
extended.put("ActiveProfile", profileName);
|
extended.put("ActiveProfile", profileName);
|
||||||
|
@ -368,7 +369,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
||||||
pump.put("battery", battery);
|
pump.put("battery", battery);
|
||||||
pump.put("status", status);
|
pump.put("status", status);
|
||||||
pump.put("extended", extended);
|
pump.put("extended", extended);
|
||||||
pump.put("reservoir", getPumpStatusData().reservoirRemainingUnits);
|
pump.put("reservoir", getPumpStatusData().getReservoirRemainingUnits());
|
||||||
pump.put("clock", dateUtil.toISOString(dateUtil.now()));
|
pump.put("clock", dateUtil.toISOString(dateUtil.now()));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
aapsLogger.error("Unhandled exception", e);
|
aapsLogger.error("Unhandled exception", e);
|
||||||
|
@ -381,14 +382,14 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public String shortStatus(boolean veryShort) {
|
public String shortStatus(boolean veryShort) {
|
||||||
String ret = "";
|
String ret = "";
|
||||||
if (getPumpStatusData().lastConnection != 0) {
|
if (getPumpStatusData().getLastConnection() != 0) {
|
||||||
long agoMsec = System.currentTimeMillis() - getPumpStatusData().lastConnection;
|
long agoMsec = System.currentTimeMillis() - getPumpStatusData().getLastConnection();
|
||||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
int agoMin = (int) (agoMsec / 60d / 1000d);
|
||||||
ret += "LastConn: " + agoMin + " min ago\n";
|
ret += "LastConn: " + agoMin + " min ago\n";
|
||||||
}
|
}
|
||||||
if (getPumpStatusData().lastBolusTime != null && getPumpStatusData().lastBolusTime.getTime() != 0) {
|
if (getPumpStatusData().getLastBolusTime() != null && getPumpStatusData().getLastBolusTime().getTime() != 0) {
|
||||||
ret += "LastBolus: " + DecimalFormatter.INSTANCE.to2Decimal(getPumpStatusData().lastBolusAmount) + "U @" + //
|
ret += "LastBolus: " + DecimalFormatter.INSTANCE.to2Decimal(getPumpStatusData().getLastBolusAmount()) + "U @" + //
|
||||||
android.text.format.DateFormat.format("HH:mm", getPumpStatusData().lastBolusTime) + "\n";
|
android.text.format.DateFormat.format("HH:mm", getPumpStatusData().getLastBolusTime()) + "\n";
|
||||||
}
|
}
|
||||||
PumpSync.PumpState.TemporaryBasal activeTemp = pumpSync.expectedPumpState().getTemporaryBasal();
|
PumpSync.PumpState.TemporaryBasal activeTemp = pumpSync.expectedPumpState().getTemporaryBasal();
|
||||||
if (activeTemp != null) {
|
if (activeTemp != null) {
|
||||||
|
@ -402,9 +403,9 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements Pump,
|
||||||
// ret += "TDD: " + DecimalFormatter.to0Decimal(pumpStatus.dailyTotalUnits) + " / "
|
// ret += "TDD: " + DecimalFormatter.to0Decimal(pumpStatus.dailyTotalUnits) + " / "
|
||||||
// + pumpStatus.maxDailyTotalUnits + " U\n";
|
// + pumpStatus.maxDailyTotalUnits + " U\n";
|
||||||
// }
|
// }
|
||||||
ret += "IOB: " + getPumpStatusData().iob + "U\n";
|
ret += "IOB: " + getPumpStatusData().getIob() + "U\n";
|
||||||
ret += "Reserv: " + DecimalFormatter.INSTANCE.to0Decimal(getPumpStatusData().reservoirRemainingUnits) + "U\n";
|
ret += "Reserv: " + DecimalFormatter.INSTANCE.to0Decimal(getPumpStatusData().getReservoirRemainingUnits()) + "U\n";
|
||||||
ret += "Batt: " + getPumpStatusData().batteryRemaining + "\n";
|
ret += "Batt: " + getPumpStatusData().getBatteryRemaining() + "\n";
|
||||||
return ret;
|
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.InvalidConfiguration -> binding.pumpStatusIcon.text = " " + resourceHelper.gs(medtronicPumpStatus.pumpDeviceState.resourceId)
|
||||||
|
|
||||||
PumpDeviceState.Active -> {
|
PumpDeviceState.Active -> {
|
||||||
val cmd = medtronicUtil.currentCommand
|
val cmd = medtronicUtil.getCurrentCommand()
|
||||||
if (cmd == null)
|
if (cmd == null)
|
||||||
binding.pumpStatusIcon.text = " " + resourceHelper.gs(medtronicPumpStatus.pumpDeviceState.resourceId)
|
binding.pumpStatusIcon.text = " " + resourceHelper.gs(medtronicPumpStatus.pumpDeviceState.resourceId)
|
||||||
else {
|
else {
|
||||||
aapsLogger.debug(LTag.PUMP, "Command: $cmd")
|
aapsLogger.debug(LTag.PUMP, "Command: $cmd")
|
||||||
val cmdResourceId = cmd.resourceId
|
val cmdResourceId = cmd.resourceId!!
|
||||||
if (cmd == MedtronicCommandType.GetHistoryData) {
|
if (cmd == MedtronicCommandType.GetHistoryData) {
|
||||||
binding.pumpStatusIcon.text = medtronicUtil.frameNumber?.let {
|
binding.pumpStatusIcon.text = medtronicUtil.frameNumber?.let {
|
||||||
resourceHelper.gs(cmdResourceId, medtronicUtil.pageNumber, medtronicUtil.frameNumber)
|
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)
|
?: resourceHelper.gs(R.string.medtronic_cmd_desc_get_history_request, medtronicUtil.pageNumber)
|
||||||
} else {
|
} else {
|
||||||
binding.pumpStatusIcon.text = " " + (cmdResourceId?.let { resourceHelper.gs(it) }
|
binding.pumpStatusIcon.text = " " + (cmdResourceId?.let { resourceHelper.gs(it) }
|
||||||
?: cmd.getCommandDescription())
|
?: cmd.commandDescription)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,34 +298,31 @@ class MedtronicFragment : DaggerFragment() {
|
||||||
val bolus = medtronicPumpStatus.lastBolusAmount
|
val bolus = medtronicPumpStatus.lastBolusAmount
|
||||||
val bolusTime = medtronicPumpStatus.lastBolusTime
|
val bolusTime = medtronicPumpStatus.lastBolusTime
|
||||||
if (bolus != null && bolusTime != null) {
|
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 bolusMinAgo = agoMsc.toDouble() / 60.0 / 1000.0
|
||||||
val unit = resourceHelper.gs(R.string.insulin_unit_shortname)
|
val unit = resourceHelper.gs(R.string.insulin_unit_shortname)
|
||||||
val ago = when {
|
val ago = when {
|
||||||
agoMsc < 60 * 1000 -> resourceHelper.gs(R.string.medtronic_pump_connected_now)
|
agoMsc < 60 * 1000 -> resourceHelper.gs(R.string.medtronic_pump_connected_now)
|
||||||
bolusMinAgo < 60 -> dateUtil.minAgo(resourceHelper, medtronicPumpStatus.lastBolusTime.time)
|
bolusMinAgo < 60 -> dateUtil.minAgo(resourceHelper, medtronicPumpStatus.lastBolusTime!!.time)
|
||||||
else -> dateUtil.hourAgo(medtronicPumpStatus.lastBolusTime.time, resourceHelper)
|
else -> dateUtil.hourAgo(medtronicPumpStatus.lastBolusTime!!.time, resourceHelper)
|
||||||
}
|
}
|
||||||
binding.lastBolus.text = resourceHelper.gs(R.string.mdt_last_bolus, bolus, unit, ago)
|
binding.lastBolus.text = resourceHelper.gs(R.string.mdt_last_bolus, bolus, unit, ago)
|
||||||
} else {
|
} else {
|
||||||
binding.lastBolus.text = ""
|
binding.lastBolus.text = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true) {
|
|
||||||
// base basal rate
|
// base basal rate
|
||||||
binding.baseBasalRate.text = ("(" + medtronicPumpStatus.activeProfileName + ") "
|
binding.baseBasalRate.text = ("(" + medtronicPumpStatus.activeProfileName + ") "
|
||||||
+ resourceHelper.gs(R.string.pump_basebasalrate, medtronicPumpPlugin.baseBasalRate))
|
+ resourceHelper.gs(R.string.pump_basebasalrate, medtronicPumpPlugin.baseBasalRate))
|
||||||
|
|
||||||
binding.tempBasal.text = "??"
|
// TBR
|
||||||
} else {
|
var tbrStr = ""
|
||||||
val pumpState = pumpSync.expectedPumpState()
|
var tbrRemainingTime: Int? = medtronicPumpStatus.tbrRemainingTime
|
||||||
// base basal rate
|
|
||||||
binding.baseBasalRate.text = ("(" + medtronicPumpStatus.activeProfileName + ") "
|
|
||||||
+ resourceHelper.gs(R.string.pump_basebasalrate, medtronicPumpPlugin.baseBasalRate))
|
|
||||||
|
|
||||||
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
|
// battery
|
||||||
if (medtronicPumpStatus.batteryType == BatteryType.None || medtronicPumpStatus.batteryVoltage == null) {
|
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.PluginDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.interfaces.Pump;
|
import info.nightscout.androidaps.interfaces.Pump;
|
||||||
|
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PumpSync;
|
import info.nightscout.androidaps.interfaces.PumpSync;
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
import info.nightscout.androidaps.logging.LTag;
|
||||||
|
@ -210,19 +211,24 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
return "MedtronicPumpPlugin::";
|
return "MedtronicPumpPlugin::";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public PumpDescription getPumpDescription() {
|
||||||
|
// return super.pumpDescription;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initPumpStatusData() {
|
public void initPumpStatusData() {
|
||||||
|
|
||||||
medtronicPumpStatus.lastConnection = sp.getLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
|
medtronicPumpStatus.setLastConnection(sp.getLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L));
|
||||||
medtronicPumpStatus.lastDataTime = medtronicPumpStatus.lastConnection;
|
medtronicPumpStatus.setLastDataTime(medtronicPumpStatus.getLastConnection());
|
||||||
medtronicPumpStatus.previousConnection = medtronicPumpStatus.lastConnection;
|
medtronicPumpStatus.setPreviousConnection( medtronicPumpStatus.getLastConnection());
|
||||||
|
|
||||||
//if (rileyLinkMedtronicService != null) rileyLinkMedtronicService.verifyConfiguration();
|
//if (rileyLinkMedtronicService != null) rileyLinkMedtronicService.verifyConfiguration();
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMP, "initPumpStatusData: " + this.medtronicPumpStatus);
|
aapsLogger.debug(LTag.PUMP, "initPumpStatusData: " + this.medtronicPumpStatus);
|
||||||
|
|
||||||
// this is only thing that can change, by being configured
|
// 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
|
// set first Medtronic Pump Start
|
||||||
if (!sp.contains(MedtronicConst.Statistics.FirstPumpStart)) {
|
if (!sp.contains(MedtronicConst.Statistics.FirstPumpStart)) {
|
||||||
|
@ -321,15 +327,16 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
return rileyLinkMedtronicService;
|
return rileyLinkMedtronicService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public RileyLinkPumpInfo getPumpInfo() {
|
@Override
|
||||||
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);
|
public RileyLinkPumpInfo getPumpInfo() {
|
||||||
String model = medtronicPumpStatus.medtronicDeviceType == null ? "???" : "Medtronic " + medtronicPumpStatus.medtronicDeviceType.getPumpModel();
|
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 serialNumber = medtronicPumpStatus.serialNumber;
|
String model = medtronicPumpStatus.getMedtronicDeviceType() == null ? "???" : "Medtronic " + medtronicPumpStatus.getMedtronicDeviceType().getPumpModel();
|
||||||
|
String serialNumber = medtronicPumpStatus.getSerialNumber();
|
||||||
return new RileyLinkPumpInfo(frequency, model, serialNumber);
|
return new RileyLinkPumpInfo(frequency, model, serialNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public long getLastConnectionTimeMillis() {
|
@Override public long getLastConnectionTimeMillis() {
|
||||||
return medtronicPumpStatus.lastConnection;
|
return medtronicPumpStatus.getLastConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void setLastCommunicationToNow() {
|
@Override public void setLastCommunicationToNow() {
|
||||||
|
@ -580,7 +587,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
if (medtronicUtil.getMedtronicPumpModel() == null) {
|
if (medtronicUtil.getMedtronicPumpModel() == null) {
|
||||||
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.PumpModel);
|
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.PumpModel);
|
||||||
} else {
|
} 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.");
|
aapsLogger.warn(LTag.PUMP, getLogPrefix() + "Configured pump is not the same as one detected.");
|
||||||
medtronicUtil.sendNotification(MedtronicNotificationType.PumpTypeNotSame, getResourceHelper(), rxBus);
|
medtronicUtil.sendNotification(MedtronicNotificationType.PumpTypeNotSame, getResourceHelper(), rxBus);
|
||||||
}
|
}
|
||||||
|
@ -643,27 +650,27 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isThisProfileSet(@NonNull Profile profile) {
|
public boolean isThisProfileSet(@NonNull Profile profile) {
|
||||||
aapsLogger.debug(LTag.PUMP, "isThisProfileSet: basalInitalized=" + medtronicPumpStatus.basalProfileStatus);
|
aapsLogger.debug(LTag.PUMP, "isThisProfileSet: basalInitalized=" + medtronicPumpStatus.getBasalProfileStatus());
|
||||||
|
|
||||||
if (!isInitialized)
|
if (!isInitialized)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (medtronicPumpStatus.basalProfileStatus == BasalProfileStatus.NotInitialized) {
|
if (medtronicPumpStatus.getBasalProfileStatus() == BasalProfileStatus.NotInitialized) {
|
||||||
// this shouldn't happen, but if there was problem we try again
|
// this shouldn't happen, but if there was problem we try again
|
||||||
getBasalProfiles();
|
getBasalProfiles();
|
||||||
return isProfileSame(profile);
|
return isProfileSame(profile);
|
||||||
} else if (medtronicPumpStatus.basalProfileStatus == BasalProfileStatus.ProfileChanged) {
|
} else if (medtronicPumpStatus.getBasalProfileStatus() == BasalProfileStatus.ProfileChanged) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (medtronicPumpStatus.basalProfileStatus != BasalProfileStatus.ProfileOK) || isProfileSame(profile);
|
return (medtronicPumpStatus.getBasalProfileStatus() != BasalProfileStatus.ProfileOK) || isProfileSame(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean isProfileSame(Profile profile) {
|
private boolean isProfileSame(Profile profile) {
|
||||||
|
|
||||||
boolean invalid = false;
|
boolean invalid = false;
|
||||||
Double[] basalsByHour = medtronicPumpStatus.basalsByHour;
|
Double[] basalsByHour = medtronicPumpStatus.getBasalsByHour();
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMP, "Current Basals (h): "
|
aapsLogger.debug(LTag.PUMP, "Current Basals (h): "
|
||||||
+ (basalsByHour == null ? "null" : BasalProfile.getProfilesByHourToString(basalsByHour)));
|
+ (basalsByHour == null ? "null" : BasalProfile.getProfilesByHourToString(basalsByHour)));
|
||||||
|
@ -704,8 +711,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
@Override
|
@Override
|
||||||
public long lastDataTime() {
|
public long lastDataTime() {
|
||||||
|
|
||||||
if (medtronicPumpStatus.lastConnection != 0) {
|
if (medtronicPumpStatus.getLastConnection() != 0) {
|
||||||
return medtronicPumpStatus.lastConnection;
|
return medtronicPumpStatus.getLastConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
return System.currentTimeMillis();
|
return System.currentTimeMillis();
|
||||||
|
@ -720,13 +727,13 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getReservoirLevel() {
|
public double getReservoirLevel() {
|
||||||
return medtronicPumpStatus.reservoirRemainingUnits;
|
return medtronicPumpStatus.getReservoirRemainingUnits();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBatteryLevel() {
|
public int getBatteryLevel() {
|
||||||
return medtronicPumpStatus.batteryRemaining;
|
return medtronicPumpStatus.getBatteryRemaining();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void triggerUIChange() {
|
protected void triggerUIChange() {
|
||||||
|
@ -778,22 +785,22 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
if (clock == null)
|
if (clock == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int timeDiff = Math.abs(clock.timeDifference);
|
int timeDiff = Math.abs(clock.getTimeDifference());
|
||||||
|
|
||||||
if (timeDiff > 20) {
|
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));
|
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);
|
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);
|
Notification notification = new Notification(Notification.INSIGHT_DATE_TIME_UPDATED, getResourceHelper().gs(R.string.pump_time_updated), Notification.INFO, 60);
|
||||||
rxBus.send(new EventNewNotification(notification));
|
rxBus.send(new EventNewNotification(notification));
|
||||||
}
|
}
|
||||||
} else {
|
} 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));
|
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);
|
medtronicUtil.sendNotification(MedtronicNotificationType.TimeChangeOver24h, getResourceHelper(), rxBus);
|
||||||
}
|
}
|
||||||
|
@ -814,12 +821,12 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
|
|
||||||
setRefreshButtonEnabled(false);
|
setRefreshButtonEnabled(false);
|
||||||
|
|
||||||
if (detailedBolusInfo.insulin > medtronicPumpStatus.reservoirRemainingUnits) {
|
if (detailedBolusInfo.insulin > medtronicPumpStatus.getReservoirRemainingUnits()) {
|
||||||
return new PumpEnactResult(getInjector()) //
|
return new PumpEnactResult(getInjector()) //
|
||||||
.success(false) //
|
.success(false) //
|
||||||
.enacted(false) //
|
.enacted(false) //
|
||||||
.comment(getResourceHelper().gs(R.string.medtronic_cmd_bolus_could_not_be_delivered_no_insulin,
|
.comment(getResourceHelper().gs(R.string.medtronic_cmd_bolus_could_not_be_delivered_no_insulin,
|
||||||
medtronicPumpStatus.reservoirRemainingUnits,
|
medtronicPumpStatus.getReservoirRemainingUnits(),
|
||||||
detailedBolusInfo.insulin));
|
detailedBolusInfo.insulin));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -857,9 +864,9 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery");
|
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery");
|
||||||
|
|
||||||
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetBolus,
|
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);
|
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.
|
// 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
|
incrementStatistics(detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB ? MedtronicConst.Statistics.SMBBoluses
|
||||||
: MedtronicConst.Statistics.StandardBoluses);
|
: MedtronicConst.Statistics.StandardBoluses);
|
||||||
|
@ -1022,7 +1029,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
|
|
||||||
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.CancelTBR);
|
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.CancelTBR);
|
||||||
|
|
||||||
Boolean response = (Boolean) responseTask2.returnData;
|
Boolean response = (Boolean) responseTask2.getResult();
|
||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
aapsLogger.info(LTag.PUMP, getLogPrefix() + "setTempBasalAbsolute - Current TBR cancelled.");
|
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
|
// now start new TBR
|
||||||
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetTemporaryBasal,
|
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);
|
aapsLogger.info(LTag.PUMP, getLogPrefix() + "setTempBasalAbsolute - setTBR. Response: " + response);
|
||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
// FIXME put this into UIPostProcessor
|
// FIXME put this into UIPostProcessor
|
||||||
medtronicPumpStatus.tempBasalStart = new Date();
|
medtronicPumpStatus.setTempBasalStart(new Date());
|
||||||
medtronicPumpStatus.tempBasalAmount = absoluteRate;
|
medtronicPumpStatus.setTempBasalAmount(absoluteRate);
|
||||||
medtronicPumpStatus.tempBasalLength = durationInMinutes;
|
medtronicPumpStatus.setTempBasalLength(durationInMinutes);
|
||||||
|
|
||||||
TemporaryBasal tempStart = new TemporaryBasal(getInjector()) //
|
TemporaryBasal tempStart = new TemporaryBasal(getInjector()) //
|
||||||
.date(System.currentTimeMillis()) //
|
.date(System.currentTimeMillis()) //
|
||||||
|
@ -1122,7 +1129,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
scheduleNextRefresh(MedtronicStatusRefreshType.PumpTime, -1);
|
scheduleNextRefresh(MedtronicStatusRefreshType.PumpTime, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.medtronicPumpStatus.basalProfileStatus != BasalProfileStatus.NotInitialized
|
if (this.medtronicPumpStatus.getBasalProfileStatus() != BasalProfileStatus.NotInitialized
|
||||||
&& medtronicHistoryData.hasBasalProfileChanged()) {
|
&& medtronicHistoryData.hasBasalProfileChanged()) {
|
||||||
medtronicHistoryData.processLastBasalProfileChange(pumpDescription.getPumpType(), medtronicPumpStatus);
|
medtronicHistoryData.processLastBasalProfileChange(pumpDescription.getPumpType(), medtronicPumpStatus);
|
||||||
}
|
}
|
||||||
|
@ -1194,7 +1201,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (debugHistory)
|
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.setIsInInit(false);
|
||||||
// medtronicHistoryData.setLastHistoryRecordTime(lastPumpHistoryEntry.atechDateTime);
|
// medtronicHistoryData.setLastHistoryRecordTime(lastPumpHistoryEntry.atechDateTime);
|
||||||
|
|
||||||
|
@ -1204,12 +1211,12 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
//aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate);
|
//aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate);
|
||||||
|
|
||||||
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetHistoryData,
|
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetHistoryData,
|
||||||
lastPumpHistoryEntry, targetDate);
|
Arrays.asList(lastPumpHistoryEntry, targetDate));
|
||||||
|
|
||||||
if (debugHistory)
|
if (debugHistory)
|
||||||
aapsLogger.debug(LTag.PUMP, "HST: After task");
|
aapsLogger.debug(LTag.PUMP, "HST: After task");
|
||||||
|
|
||||||
PumpHistoryResult historyResult = (PumpHistoryResult) responseTask2.returnData;
|
PumpHistoryResult historyResult = (PumpHistoryResult) responseTask2.getResult();
|
||||||
|
|
||||||
if (debugHistory)
|
if (debugHistory)
|
||||||
aapsLogger.debug(LTag.PUMP, "HST: History Result: " + historyResult.toString());
|
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());
|
sp.putLong(MedtronicConst.Statistics.LastPumpHistoryEntry, latestEntry.getAtechDateTime());
|
||||||
|
|
||||||
if (debugHistory)
|
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.addNewHistory(historyResult);
|
||||||
this.medtronicHistoryData.filterNewEntries();
|
this.medtronicHistoryData.filterNewEntries();
|
||||||
|
@ -1281,7 +1288,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
switch (refreshType) {
|
switch (refreshType) {
|
||||||
|
|
||||||
case RemainingInsulin: {
|
case RemainingInsulin: {
|
||||||
double remaining = medtronicPumpStatus.reservoirRemainingUnits;
|
double remaining = medtronicPumpStatus.getReservoirRemainingUnits();
|
||||||
int min;
|
int min;
|
||||||
if (remaining > 50)
|
if (remaining > 50)
|
||||||
min = 4 * 60;
|
min = 4 * 60;
|
||||||
|
@ -1348,7 +1355,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.ReadTemporaryBasal);
|
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.ReadTemporaryBasal);
|
||||||
|
|
||||||
if (responseTask.hasData()) {
|
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
|
// we sometimes get rate returned even if TBR is no longer running
|
||||||
if (tbr.getDurationMinutes() == 0) {
|
if (tbr.getDurationMinutes() == 0) {
|
||||||
|
@ -1397,7 +1404,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
|
|
||||||
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.CancelTBR);
|
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.CancelTBR);
|
||||||
|
|
||||||
Boolean response = (Boolean) responseTask2.returnData;
|
Boolean response = (Boolean) responseTask2.getResult();
|
||||||
|
|
||||||
finishAction("TBR");
|
finishAction("TBR");
|
||||||
|
|
||||||
|
@ -1434,7 +1441,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
|
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public String serialNumber() {
|
public String serialNumber() {
|
||||||
return medtronicPumpStatus.serialNumber;
|
return medtronicPumpStatus.getSerialNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
|
@ -1465,6 +1472,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
|
|
||||||
BasalProfile basalProfile = convertProfileToMedtronicProfile(profile);
|
BasalProfile basalProfile = convertProfileToMedtronicProfile(profile);
|
||||||
|
|
||||||
|
aapsLogger.debug("Basal Profile: " + basalProfile);
|
||||||
|
|
||||||
String profileInvalid = isProfileValid(basalProfile);
|
String profileInvalid = isProfileValid(basalProfile);
|
||||||
|
|
||||||
if (profileInvalid != null) {
|
if (profileInvalid != null) {
|
||||||
|
@ -1475,9 +1484,9 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements Pump, Ril
|
||||||
}
|
}
|
||||||
|
|
||||||
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetBasalProfileSTD,
|
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);
|
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();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
|
||||||
if (medtronicPumpStatus.maxBasal == null)
|
if (medtronicPumpStatus.getMaxBasal() == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
for (BasalProfileEntry profileEntry : basalProfile.getEntries()) {
|
for (BasalProfileEntry profileEntry : basalProfile.getEntries()) {
|
||||||
|
|
||||||
if (profileEntry.getRate() > medtronicPumpStatus.maxBasal) {
|
if (profileEntry.getRate() > medtronicPumpStatus.getMaxBasal()) {
|
||||||
stringBuilder.append(profileEntry.getStartTime().toString("HH:mm"));
|
stringBuilder.append(profileEntry.getStartTime().toString("HH:mm"));
|
||||||
stringBuilder.append("=");
|
stringBuilder.append("=");
|
||||||
stringBuilder.append(profileEntry.getRate());
|
stringBuilder.append(profileEntry.getRate());
|
||||||
|
|
|
@ -80,8 +80,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
@Inject
|
@Inject
|
||||||
public void onInit() {
|
public void onInit() {
|
||||||
// we can't do this in the constructor, as sp only gets injected after the constructor has returned
|
// we can't do this in the constructor, as sp only gets injected after the constructor has returned
|
||||||
medtronicPumpStatus.previousConnection = sp.getLong(
|
medtronicPumpStatus.setPreviousConnection(sp.getLong(
|
||||||
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
|
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -136,7 +136,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
|
|
||||||
if (!canPreventTuneUp) {
|
if (!canPreventTuneUp) {
|
||||||
|
|
||||||
long diff = System.currentTimeMillis() - medtronicPumpStatus.lastConnection;
|
long diff = System.currentTimeMillis() - medtronicPumpStatus.getLastConnection();
|
||||||
|
|
||||||
if (diff > RILEYLINK_TIMEOUT) {
|
if (diff > RILEYLINK_TIMEOUT) {
|
||||||
serviceTaskExecutor.startTask(new WakeAndTuneTask(injector));
|
serviceTaskExecutor.startTask(new WakeAndTuneTask(injector));
|
||||||
|
@ -278,7 +278,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
|
|
||||||
for (List<Byte> frame : frames) {
|
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));
|
// aapsLogger.debug(LTag.PUMPCOMM,"Frame {} data:\n{}", frameNr, ByteUtil.getCompactString(frameData));
|
||||||
|
|
||||||
|
@ -570,7 +570,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
try {
|
try {
|
||||||
PumpMessage response = sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
|
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) {
|
if (check == null) {
|
||||||
|
|
||||||
|
@ -632,11 +632,11 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
|
|
||||||
// PUMP SPECIFIC COMMANDS
|
// PUMP SPECIFIC COMMANDS
|
||||||
|
|
||||||
public Float getRemainingInsulin() {
|
public Double getRemainingInsulin() {
|
||||||
|
|
||||||
Object responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.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.getRawContent()));
|
||||||
// aapsLogger.debug(LTag.PUMPCOMM,"1st Response: " + HexDump.toHexStringDisplayable(response.getMessageBody().getTxData()));
|
// 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;
|
byte[] data = null;
|
||||||
|
|
||||||
|
@ -695,7 +695,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
// aapsLogger.debug(LTag.PUMPCOMM,"{} Response: {}", runs,
|
// aapsLogger.debug(LTag.PUMPCOMM,"{} Response: {}", runs,
|
||||||
// HexDump.toHexStringDisplayable(response2.getMessageBody().getTxData()));
|
// HexDump.toHexStringDisplayable(response2.getMessageBody().getTxData()));
|
||||||
|
|
||||||
String check2 = checkResponseContent(response, commandType.commandDescription, 1);
|
String check2 = checkResponseContent(response, commandType.getCommandDescription(), 1);
|
||||||
|
|
||||||
if (check2 == null) {
|
if (check2 == null) {
|
||||||
|
|
||||||
|
@ -765,12 +765,12 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
public ClockDTO getPumpTime() {
|
public ClockDTO getPumpTime() {
|
||||||
|
|
||||||
ClockDTO clockDTO = new ClockDTO();
|
ClockDTO clockDTO = new ClockDTO();
|
||||||
clockDTO.localDeviceTime = new LocalDateTime();
|
clockDTO.setLocalDeviceTime(new LocalDateTime());
|
||||||
|
|
||||||
Object responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.GetRealTimeClock);
|
Object responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.GetRealTimeClock);
|
||||||
|
|
||||||
if (responseObject != null) {
|
if (responseObject != null) {
|
||||||
clockDTO.pumpTime = (LocalDateTime) responseObject;
|
clockDTO.setPumpTime((LocalDateTime) responseObject);
|
||||||
return clockDTO;
|
return clockDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ class MedtronicConverter @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
MedtronicCommandType.ReadTemporaryBasal -> {
|
MedtronicCommandType.ReadTemporaryBasal -> {
|
||||||
TempBasalPair(aapsLogger, rawContent) // 5
|
TempBasalPair(aapsLogger, rawContent!!) // 5
|
||||||
}
|
}
|
||||||
|
|
||||||
MedtronicCommandType.Settings_512 -> {
|
MedtronicCommandType.Settings_512 -> {
|
||||||
|
@ -112,7 +112,7 @@ class MedtronicConverter @Inject constructor(
|
||||||
batteryStatus.batteryStatusType = BatteryStatusDTO.BatteryStatusType.Unknown
|
batteryStatus.batteryStatusType = BatteryStatusDTO.BatteryStatusType.Unknown
|
||||||
}
|
}
|
||||||
if (rawData.size > 1) {
|
if (rawData.size > 1) {
|
||||||
var d: Double? = null
|
var d: Double? //= null
|
||||||
|
|
||||||
// if response in 3 bytes then we add additional information
|
// if response in 3 bytes then we add additional information
|
||||||
d = if (rawData.size == 2) {
|
d = if (rawData.size == 2) {
|
||||||
|
@ -126,7 +126,7 @@ class MedtronicConverter @Inject constructor(
|
||||||
return batteryStatus
|
return batteryStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun decodeRemainingInsulin(rawData: ByteArray?): Float {
|
private fun decodeRemainingInsulin(rawData: ByteArray?): Double {
|
||||||
var startIdx = 0
|
var startIdx = 0
|
||||||
val pumpModel = medtronicUtil.medtronicPumpModel
|
val pumpModel = medtronicUtil.medtronicPumpModel
|
||||||
val strokes = pumpModel?.bolusStrokes ?: 10
|
val strokes = pumpModel?.bolusStrokes ?: 10
|
||||||
|
@ -134,11 +134,11 @@ class MedtronicConverter @Inject constructor(
|
||||||
startIdx = 2
|
startIdx = 2
|
||||||
}
|
}
|
||||||
val reqLength = startIdx + 1
|
val reqLength = startIdx + 1
|
||||||
var value = 0f
|
var value = 0.0
|
||||||
value = if (reqLength >= rawData!!.size) {
|
value = if (reqLength >= rawData!!.size) {
|
||||||
rawData[startIdx] / (1.0f * strokes)
|
rawData[startIdx] / (1.0 * strokes)
|
||||||
} else {
|
} 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")
|
aapsLogger.debug(LTag.PUMPCOMM, "Remaining insulin: $value")
|
||||||
return value
|
return value
|
||||||
|
@ -208,7 +208,7 @@ class MedtronicConverter @Inject constructor(
|
||||||
rd[settingIndexMaxBasal + 1].toInt())), PumpConfigurationGroup.Basal, map)
|
rd[settingIndexMaxBasal + 1].toInt())), PumpConfigurationGroup.Basal, map)
|
||||||
addSettingToMap("CFG_BASE_CLOCK_MODE", if (rd[settingIndexTimeDisplayFormat].toInt() == 0) "12h" else "24h",
|
addSettingToMap("CFG_BASE_CLOCK_MODE", if (rd[settingIndexTimeDisplayFormat].toInt() == 0) "12h" else "24h",
|
||||||
PumpConfigurationGroup.General, map)
|
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,
|
addSettingToMap("PCFG_INSULIN_CONCENTRATION", "" + if (rd[9].toInt() == 0) 50 else 100, PumpConfigurationGroup.Insulin,
|
||||||
map)
|
map)
|
||||||
// LOG.debug("Insulin concentration: " + rd[9]);
|
// LOG.debug("Insulin concentration: " + rd[9]);
|
||||||
|
@ -249,7 +249,7 @@ class MedtronicConverter @Inject constructor(
|
||||||
addSettingToMap("PCFG_MM_SRESERVOIR_WARNING_POINT", "" + ByteUtil.asUINT8(rd[19]),
|
addSettingToMap("PCFG_MM_SRESERVOIR_WARNING_POINT", "" + ByteUtil.asUINT8(rd[19]),
|
||||||
PumpConfigurationGroup.Other, map)
|
PumpConfigurationGroup.Other, map)
|
||||||
addSettingToMap("CFG_MM_KEYPAD_LOCKED", parseResultEnable(rd[20].toInt()), 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_BOLUS_SCROLL_STEP_SIZE", "" + rd[21], PumpConfigurationGroup.Bolus, map)
|
||||||
addSettingToMap("PCFG_CAPTURE_EVENT_ENABLE", parseResultEnable(rd[22].toInt()), PumpConfigurationGroup.Other, 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)
|
addSettingToMap("PCFG_OTHER_DEVICE_ENABLE", parseResultEnable(rd[23].toInt()), PumpConfigurationGroup.Other, map)
|
||||||
|
@ -273,7 +273,7 @@ class MedtronicConverter @Inject constructor(
|
||||||
|
|
||||||
// 512
|
// 512
|
||||||
private fun decodeInsulinActionSetting(ai: ByteArray, map: MutableMap<String, PumpSettingDTO>) {
|
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",
|
addSettingToMap("PCFG_INSULIN_ACTION_TYPE", if (ai[17].toInt() != 0) "Regular" else "Fast",
|
||||||
PumpConfigurationGroup.Insulin, map)
|
PumpConfigurationGroup.Insulin, map)
|
||||||
} else {
|
} else {
|
||||||
|
@ -297,10 +297,10 @@ class MedtronicConverter @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private val settingIndexMaxBasal: Int
|
private val settingIndexMaxBasal: Int
|
||||||
private get() = if (is523orHigher()) 7 else 6
|
get() = if (is523orHigher()) 7 else 6
|
||||||
|
|
||||||
private val settingIndexTimeDisplayFormat: Int
|
private val settingIndexTimeDisplayFormat: Int
|
||||||
private get() = if (is523orHigher()) 9 else 8
|
get() = if (is523orHigher()) 9 else 8
|
||||||
|
|
||||||
private fun decodeMaxBolus(ai: ByteArray?): Double {
|
private fun decodeMaxBolus(ai: ByteArray?): Double {
|
||||||
return if (is523orHigher()) decodeBolusInsulin(ByteUtil.toInt(ai!![5], ai[6])) else decodeBolusInsulin(ByteUtil
|
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 {
|
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> {
|
private fun checkPage(page: RawHistoryPage, partial: Boolean): List<Byte> {
|
||||||
val byteList: List<Byte> = ArrayList()
|
val byteList: List<Byte> = ArrayList()
|
||||||
|
|
||||||
if (medtronicUtil!!.medtronicPumpModel == null) {
|
if (medtronicUtil.medtronicPumpModel == null) {
|
||||||
aapsLogger!!.error(LTag.PUMPCOMM, "Device Type is not defined.")
|
aapsLogger.error(LTag.PUMPCOMM, "Device Type is not defined.")
|
||||||
return byteList
|
return byteList
|
||||||
}
|
}
|
||||||
return if (page.data.size != 1024) {
|
return if (page.data.size != 1024) {
|
||||||
|
@ -82,9 +82,9 @@ abstract class MedtronicHistoryDecoder<T : MedtronicHistoryEntry?> : MedtronicHi
|
||||||
for ((key) in unknownOpCodes!!) {
|
for ((key) in unknownOpCodes!!) {
|
||||||
StringUtil.appendToStringBuilder(sb, "" + key, ", ")
|
StringUtil.appendToStringBuilder(sb, "" + key, ", ")
|
||||||
}
|
}
|
||||||
aapsLogger!!.info(LTag.PUMPCOMM, "STATISTICS OF PUMP DECODE")
|
aapsLogger.info(LTag.PUMPCOMM, "STATISTICS OF PUMP DECODE")
|
||||||
if (unknownOpCodes!!.size > 0) {
|
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!!) {
|
for ((key, value) in mapStatistics!!) {
|
||||||
sb = StringBuilder()
|
sb = StringBuilder()
|
||||||
|
@ -94,9 +94,9 @@ abstract class MedtronicHistoryDecoder<T : MedtronicHistoryEntry?> : MedtronicHi
|
||||||
StringUtil.appendToStringBuilder(sb, key1, ", ")
|
StringUtil.appendToStringBuilder(sb, key1, ", ")
|
||||||
}
|
}
|
||||||
val spaces = StringUtils.repeat(" ", 14 - key.name.length)
|
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 {
|
} 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) {
|
if (!doNotProcess) {
|
||||||
head = ByteArray(headLength - 1)
|
head = ByteArray(headLength - 1)
|
||||||
for (i in 1 until headLength) {
|
for (i in 1 until headLength) {
|
||||||
head!![i - 1] = listRawData!![i]!!
|
head!![i - 1] = listRawData[i]
|
||||||
}
|
}
|
||||||
if (dateTimeLength > 0) {
|
if (dateTimeLength > 0) {
|
||||||
datetime = ByteArray(dateTimeLength)
|
datetime = ByteArray(dateTimeLength)
|
||||||
|
@ -99,7 +99,7 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
|
||||||
var i = headLength + dateTimeLength
|
var i = headLength + dateTimeLength
|
||||||
var j = 0
|
var j = 0
|
||||||
while (j < bodyLength) {
|
while (j < bodyLength) {
|
||||||
body!![j] = listRawData!![i]!!
|
body!![j] = listRawData[i]
|
||||||
i++
|
i++
|
||||||
j++
|
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,
|
aapsLogger.error(LTag.PUMPBTCOMM, String.format(Locale.ENGLISH, "Stored CRC (%d) is different than calculated (%d), but ignored for now.", crcStored,
|
||||||
crcCalculated))
|
crcCalculated))
|
||||||
} else {
|
} else {
|
||||||
if (MedtronicUtil.isLowLevelDebug()) aapsLogger.debug(LTag.PUMPBTCOMM, "CRC ok.")
|
if (MedtronicUtil.isLowLevelDebug) aapsLogger.debug(LTag.PUMPBTCOMM, "CRC ok.")
|
||||||
}
|
}
|
||||||
return crcCalculated == crcStored
|
return crcCalculated == crcStored
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
||||||
return outList
|
return outList
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
val opCode: Int = dataClear[counter]!!.toInt()
|
val opCode: Int = dataClear[counter].toInt()
|
||||||
var special = false
|
var special = false
|
||||||
incompletePacket = false
|
incompletePacket = false
|
||||||
var skippedRecords = false
|
var skippedRecords = false
|
||||||
|
@ -69,7 +69,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
||||||
}
|
}
|
||||||
val entryType = getByCode(opCode.toByte())
|
val entryType = getByCode(opCode.toByte())
|
||||||
val pe = PumpHistoryEntry()
|
val pe = PumpHistoryEntry()
|
||||||
pe.setEntryType(medtronicUtil!!.medtronicPumpModel, entryType!!)
|
pe.setEntryType(medtronicUtil.medtronicPumpModel!!, entryType!!)
|
||||||
pe.offset = counter
|
pe.offset = counter
|
||||||
counter++
|
counter++
|
||||||
if (counter >= 1022) {
|
if (counter >= 1022) {
|
||||||
|
@ -91,7 +91,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
||||||
}
|
}
|
||||||
special = true
|
special = true
|
||||||
} else {
|
} else {
|
||||||
for (j in 0 until entryType.getTotalLength(medtronicUtil.medtronicPumpModel) - 1) {
|
for (j in 0 until entryType.getTotalLength(medtronicUtil.medtronicPumpModel!!) - 1) {
|
||||||
try {
|
try {
|
||||||
listRawData.add(dataClear[counter])
|
listRawData.add(dataClear[counter])
|
||||||
counter++
|
counter++
|
||||||
|
@ -111,7 +111,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
||||||
if (pe.entryType === PumpHistoryEntryType.UnknownBasePacket) {
|
if (pe.entryType === PumpHistoryEntryType.UnknownBasePacket) {
|
||||||
pe.opCode = opCode.toByte()
|
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)
|
pe.setData(listRawData as List<Byte>, special)
|
||||||
val decoded = decodeRecord(pe)
|
val decoded = decodeRecord(pe)
|
||||||
if (decoded === RecordDecodeStatus.OK || decoded === RecordDecodeStatus.Ignored) {
|
if (decoded === RecordDecodeStatus.OK || decoded === RecordDecodeStatus.Ignored) {
|
||||||
|
@ -235,7 +235,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
||||||
val offset = body!![0] * 1000 * 30 * 60
|
val offset = body!![0] * 1000 * 30 * 60
|
||||||
var rate: Float? = null
|
var rate: Float? = null
|
||||||
val index = entry.head!![0].toInt()
|
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
|
rate = body[1] * 0.025f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
||||||
val body = entry.body!!
|
val body = entry.body!!
|
||||||
val dto = BolusWizardDTO()
|
val dto = BolusWizardDTO()
|
||||||
var bolusStrokes = 10.0f
|
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
|
// https://github.com/ps2/minimed_rf/blob/master/lib/minimed_rf/log_entries/bolus_wizard.rb#L102
|
||||||
bolusStrokes = 40.0f
|
bolusStrokes = 40.0f
|
||||||
dto.carbs = ((body[1] and 0x0c.toByte()).toInt() shl 6) + body[0]
|
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]) /
|
// carb_ratio (?) = (((self.body[2] & 0x07) << 8) + self.body[3]) /
|
||||||
// 10.0s
|
// 10.0s
|
||||||
dto.insulinSensitivity = body[4].toFloat()
|
dto.insulinSensitivity = body[4].toFloat()
|
||||||
dto.bgTargetLow = body[5] as Int
|
dto.bgTargetLow = body[5].toInt()
|
||||||
dto.bgTargetHigh = body[14] as Int
|
dto.bgTargetHigh = body[14].toInt()
|
||||||
dto.correctionEstimate = (((body[9] and 0x38).toInt() shl 5) + body[6]) / bolusStrokes
|
dto.correctionEstimate = (((body[9] and 0x38).toInt() shl 5) + body[6]) / bolusStrokes
|
||||||
dto.foodEstimate = ((body[7].toInt() shl 8) + body[8]) / bolusStrokes
|
dto.foodEstimate = ((body[7].toInt() shl 8) + body[8]) / bolusStrokes
|
||||||
dto.unabsorbedInsulin = ((body[10].toInt() shl 8) + body[11]) / bolusStrokes
|
dto.unabsorbedInsulin = ((body[10].toInt() shl 8) + body[11]) / bolusStrokes
|
||||||
dto.bolusTotal = ((body[12].toInt() shl 8) + body[13]) / bolusStrokes
|
dto.bolusTotal = ((body[12].toInt() shl 8) + body[13]) / bolusStrokes
|
||||||
} else {
|
} else {
|
||||||
dto.bloodGlucose = (body.get(1) and 0x0F).toInt() shl 8 or entry.head!!.get(0).toInt()
|
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.carbRatio = body.get(2).toFloat()
|
||||||
dto.insulinSensitivity = body.get(3).toFloat()
|
dto.insulinSensitivity = body.get(3).toFloat()
|
||||||
dto.bgTargetLow = body.get(4) as Int
|
dto.bgTargetLow = body.get(4).toInt()
|
||||||
dto.bgTargetHigh = body.get(12) as Int
|
dto.bgTargetHigh = body.get(12).toInt()
|
||||||
dto.bolusTotal = body.get(11) / bolusStrokes
|
dto.bolusTotal = body.get(11) / bolusStrokes
|
||||||
dto.foodEstimate = body.get(6) / bolusStrokes
|
dto.foodEstimate = body.get(6) / bolusStrokes
|
||||||
dto.unabsorbedInsulin = body.get(9) / bolusStrokes
|
dto.unabsorbedInsulin = body.get(9) / bolusStrokes
|
||||||
|
@ -359,7 +359,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
||||||
private fun decodeBolus(entry: PumpHistoryEntry) {
|
private fun decodeBolus(entry: PumpHistoryEntry) {
|
||||||
val bolus = BolusDTO()
|
val bolus = BolusDTO()
|
||||||
val data = entry.head!!
|
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.requestedAmount = ByteUtil.toInt(data.get(0), data.get(1)) / 40.0
|
||||||
bolus.deliveredAmount = ByteUtil.toInt(data.get(2), data.get(3)) / 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
|
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.deliveredAmount = ByteUtil.asUINT8(data.get(1)) / 10.0
|
||||||
bolus.duration = ByteUtil.asUINT8(data.get(2)) * 30
|
bolus.duration = ByteUtil.asUINT8(data.get(2)) * 30
|
||||||
}
|
}
|
||||||
bolus.bolusType = if (bolus.duration != null && bolus.duration > 0) PumpBolusType.Extended else PumpBolusType.Normal
|
bolus.bolusType = if (bolus.duration != null && bolus.duration!! > 0) PumpBolusType.Extended else PumpBolusType.Normal
|
||||||
bolus.setAtechDateTime(entry.atechDateTime!!)
|
bolus.atechDateTime = entry.atechDateTime!!
|
||||||
entry.addDecodedData("Object", bolus)
|
entry.addDecodedData("Object", bolus)
|
||||||
entry.displayableValue = bolus.displayableValue
|
entry.displayableValue = bolus.displayableValue
|
||||||
}
|
}
|
||||||
|
@ -404,10 +404,10 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
||||||
// tbrDuration.getHead()[0],
|
// tbrDuration.getHead()[0],
|
||||||
// (ByteUtil.asUINT8(tbrRate.getDatetime()[4]) >> 3) == 0);
|
// (ByteUtil.asUINT8(tbrRate.getDatetime()[4]) >> 3) == 0);
|
||||||
val tbr = TempBasalPair(
|
val tbr = TempBasalPair(
|
||||||
tbrRate!!.head!!.get(0),
|
tbrRate.head!!.get(0),
|
||||||
tbrRate!!.body!!.get(0),
|
tbrRate.body!!.get(0),
|
||||||
tbrDuration!!.head!!.get(0).toInt(),
|
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()
|
// System.out.println("TBR: amount=" + tbr.getInsulinRate() + ", duration=" + tbr.getDurationMinutes()
|
||||||
// // + " min. Packed: " + tbr.getValue()
|
// // + " min. Packed: " + tbr.getValue()
|
||||||
|
@ -464,13 +464,13 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fix2DigitYear(year: Int): Int {
|
private fun fix2DigitYear(year: Int): Int {
|
||||||
var year = year
|
var yearInternal = year
|
||||||
year += if (year > 90) {
|
yearInternal += if (yearInternal > 90) {
|
||||||
1900
|
1900
|
||||||
} else {
|
} else {
|
||||||
2000
|
2000
|
||||||
}
|
}
|
||||||
return year
|
return yearInternal
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -35,16 +35,16 @@ class PumpHistoryEntry : MedtronicHistoryEntry() {
|
||||||
field = value
|
field = value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setEntryType(medtronicDeviceType: MedtronicDeviceType?, entryType: PumpHistoryEntryType) {
|
fun setEntryType(medtronicDeviceType: MedtronicDeviceType, entryType: PumpHistoryEntryType) {
|
||||||
this.entryType = entryType
|
this.entryType = entryType
|
||||||
sizes[0] = entryType.getHeadLength(medtronicDeviceType)
|
sizes[0] = entryType.getHeadLength(medtronicDeviceType)
|
||||||
sizes[1] = entryType.dateLength
|
sizes[1] = entryType.dateLength
|
||||||
sizes[2] = entryType.getBodyLength(medtronicDeviceType)
|
sizes[2] = entryType.getBodyLength(medtronicDeviceType)
|
||||||
if (this.entryType != null && atechDateTime != null) setPumpId()
|
if (this.entryType != null && atechDateTime != null) generatePumpId()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setPumpId() {
|
private fun generatePumpId() : Long {
|
||||||
pumpId = entryType!!.code + atechDateTime!! * 1000L
|
return entryType!!.code + atechDateTime!! * 1000L
|
||||||
}
|
}
|
||||||
|
|
||||||
override val toStringStart: String
|
override val toStringStart: String
|
||||||
|
@ -105,7 +105,7 @@ class PumpHistoryEntry : MedtronicHistoryEntry() {
|
||||||
|
|
||||||
override var pumpId: Long? = null
|
override var pumpId: Long? = null
|
||||||
get() {
|
get() {
|
||||||
setPumpId()
|
field = generatePumpId()
|
||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
set(pumpId) {
|
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) : 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) {}
|
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) {
|
return if (hasSpecialRules) {
|
||||||
getHeadLength(medtronicDeviceType) + getBodyLength(medtronicDeviceType) + dateLength
|
getHeadLength(medtronicDeviceType) + getBodyLength(medtronicDeviceType) + dateLength
|
||||||
} else {
|
} else {
|
||||||
|
@ -220,10 +220,6 @@ enum class PumpHistoryEntryType // implements CodeEnum
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private fun hasSpecialRules(): Boolean {
|
|
||||||
// return hasSpecialRules
|
|
||||||
// }
|
|
||||||
|
|
||||||
fun addSpecialRuleHead(rule: SpecialRule) {
|
fun addSpecialRuleHead(rule: SpecialRule) {
|
||||||
if (isEmpty(specialRulesHead)) {
|
if (isEmpty(specialRulesHead)) {
|
||||||
specialRulesHead = ArrayList()
|
specialRulesHead = ArrayList()
|
||||||
|
@ -244,7 +240,7 @@ enum class PumpHistoryEntryType // implements CodeEnum
|
||||||
// return description ?: name
|
// return description ?: name
|
||||||
// }
|
// }
|
||||||
|
|
||||||
fun getHeadLength(medtronicDeviceType: MedtronicDeviceType?): Int {
|
fun getHeadLength(medtronicDeviceType: MedtronicDeviceType): Int {
|
||||||
return if (hasSpecialRules) {
|
return if (hasSpecialRules) {
|
||||||
if (isNotEmpty(specialRulesHead)) {
|
if (isNotEmpty(specialRulesHead)) {
|
||||||
determineSizeByRule(medtronicDeviceType, headLength, 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) {
|
return if (hasSpecialRules) {
|
||||||
if (isNotEmpty(specialRulesBody)) {
|
if (isNotEmpty(specialRulesBody)) {
|
||||||
determineSizeByRule(medtronicDeviceType, bodyLength, specialRulesBody)
|
determineSizeByRule(medtronicDeviceType, bodyLength, specialRulesBody)
|
||||||
|
@ -277,7 +273,7 @@ enum class PumpHistoryEntryType // implements CodeEnum
|
||||||
}
|
}
|
||||||
|
|
||||||
// byte[] dh = { 2, 3 };
|
// 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
|
var size = defaultValue
|
||||||
for (rule in rules!!) {
|
for (rule in rules!!) {
|
||||||
if (MedtronicDeviceType.isSameDevice(medtronicDeviceType, rule.deviceType)) {
|
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.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
|
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* History page contains data, sorted from newest to oldest (0=newest..n=oldest)
|
* 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 val searchEntry: PumpHistoryEntry? = null
|
||||||
private var searchDate: Long? = null
|
private var searchDate: Long? = null
|
||||||
private var searchType = SearchType.None
|
private var searchType = SearchType.None
|
||||||
@JvmField var unprocessedEntries: List<PumpHistoryEntry?>? = null
|
var unprocessedEntries: List<PumpHistoryEntry> = ArrayList()
|
||||||
@JvmField var validEntries: MutableList<PumpHistoryEntry?>?
|
var validEntries: MutableList<PumpHistoryEntry> = ArrayList()
|
||||||
fun addHistoryEntries(entries: List<PumpHistoryEntry?>?, page: Int) {
|
|
||||||
|
|
||||||
|
fun addHistoryEntries(entries: List<PumpHistoryEntry>, page: Int) {
|
||||||
unprocessedEntries = entries
|
unprocessedEntries = entries
|
||||||
//aapsLogger.debug(LTag.PUMPCOMM,"PumpHistoryResult. Unprocessed entries: {}", MedtronicUtil.getGsonInstance().toJson(entries));
|
//aapsLogger.debug(LTag.PUMPCOMM,"PumpHistoryResult. Unprocessed entries: {}", MedtronicUtil.getGsonInstance().toJson(entries));
|
||||||
processEntries()
|
processEntries()
|
||||||
|
@ -32,7 +35,7 @@ class PumpHistoryResult(private val aapsLogger: AAPSLogger, searchEntry: PumpHis
|
||||||
Collections.reverse(unprocessedEntries)
|
Collections.reverse(unprocessedEntries)
|
||||||
when (searchType) {
|
when (searchType) {
|
||||||
SearchType.None -> //aapsLogger.debug(LTag.PUMPCOMM,"PE. None search");
|
SearchType.None -> //aapsLogger.debug(LTag.PUMPCOMM,"PE. None search");
|
||||||
validEntries!!.addAll(unprocessedEntries!!)
|
validEntries.addAll(unprocessedEntries)
|
||||||
|
|
||||||
SearchType.LastEntry -> {
|
SearchType.LastEntry -> {
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "PE. Last entry search")
|
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());
|
//Collections.sort(this.unprocessedEntries, new PumpHistoryEntry.Comparator());
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "PE. PumpHistoryResult. Search entry date: " + searchEntry!!.atechDateTime)
|
aapsLogger.debug(LTag.PUMPCOMM, "PE. PumpHistoryResult. Search entry date: " + searchEntry!!.atechDateTime)
|
||||||
val date = searchEntry.atechDateTime
|
val date = searchEntry.atechDateTime
|
||||||
for (unprocessedEntry in unprocessedEntries!!) {
|
for (unprocessedEntry in unprocessedEntries) {
|
||||||
if (unprocessedEntry!!.equals(searchEntry)) {
|
if (unprocessedEntry.equals(searchEntry)) {
|
||||||
//aapsLogger.debug(LTag.PUMPCOMM,"PE. Item found {}.", unprocessedEntry);
|
//aapsLogger.debug(LTag.PUMPCOMM,"PE. Item found {}.", unprocessedEntry);
|
||||||
isSearchFinished = true
|
isSearchFinished = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
//aapsLogger.debug(LTag.PUMPCOMM,"PE. Entry {} added.", unprocessedEntry);
|
//aapsLogger.debug(LTag.PUMPCOMM,"PE. Entry {} added.", unprocessedEntry);
|
||||||
validEntries!!.add(unprocessedEntry)
|
validEntries.add(unprocessedEntry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchType.Date -> {
|
SearchType.Date -> {
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "PE. Date search: Search date: " + searchDate)
|
aapsLogger.debug(LTag.PUMPCOMM, "PE. Date search: Search date: " + searchDate)
|
||||||
for (unprocessedEntry in unprocessedEntries!!) {
|
for (unprocessedEntry in unprocessedEntries) {
|
||||||
if (unprocessedEntry!!.atechDateTime == null || unprocessedEntry.atechDateTime == 0L) {
|
if (unprocessedEntry.atechDateTime == null || unprocessedEntry.atechDateTime == 0L) {
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "PE. PumpHistoryResult. Search entry date: Entry with no date: $unprocessedEntry")
|
aapsLogger.debug(LTag.PUMPCOMM, "PE. PumpHistoryResult. Search entry date: Entry with no date: $unprocessedEntry")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (unprocessedEntry.isAfter(searchDate!!)) {
|
if (unprocessedEntry.isAfter(searchDate!!)) {
|
||||||
validEntries!!.add(unprocessedEntry)
|
validEntries.add(unprocessedEntry)
|
||||||
} else {
|
} else {
|
||||||
// aapsLogger.debug(LTag.PUMPCOMM,"PE. PumpHistoryResult. Not after.. Unprocessed Entry [year={},entry={}]",
|
// aapsLogger.debug(LTag.PUMPCOMM,"PE. PumpHistoryResult. Not after.. Unprocessed Entry [year={},entry={}]",
|
||||||
// DateTimeUtil.getYear(unprocessedEntry.atechDateTime), unprocessedEntry);
|
// DateTimeUtil.getYear(unprocessedEntry.atechDateTime), unprocessedEntry);
|
||||||
|
@ -85,35 +88,19 @@ class PumpHistoryResult(private val aapsLogger: AAPSLogger, searchEntry: PumpHis
|
||||||
", searchType=" + searchType + //
|
", searchType=" + searchType + //
|
||||||
", searchFinished=" + isSearchFinished + //
|
", 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 latest entry (entry with highest date time)
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
val latestEntry: PumpHistoryEntry?
|
val latestEntry: PumpHistoryEntry?
|
||||||
get() = if (validEntries == null || validEntries!!.size == 0) null else {
|
get() = if (validEntries.size == 0) null else validEntries[0]
|
||||||
validEntries!![0]
|
|
||||||
// PumpHistoryEntry pumpHistoryEntry = this.validEntries.get(0);
|
|
||||||
//
|
|
||||||
// if (pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.EndResultTotals)
|
|
||||||
// return pumpHistoryEntry;
|
|
||||||
// else
|
|
||||||
// return this.validEntries.get(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
val isSearchRequired: Boolean
|
|
||||||
get() = searchType != SearchType.None
|
|
||||||
|
|
||||||
fun getValidEntries(): List<PumpHistoryEntry?>? {
|
// val isSearchRequired: Boolean
|
||||||
return validEntries
|
// get() = searchType != SearchType.None
|
||||||
}
|
|
||||||
|
|
||||||
internal enum class SearchType {
|
internal enum class SearchType {
|
||||||
None, //
|
None, //
|
||||||
|
@ -139,6 +126,6 @@ class PumpHistoryResult(private val aapsLogger: AAPSLogger, searchEntry: PumpHis
|
||||||
}
|
}
|
||||||
|
|
||||||
// this.unprocessedEntries = new ArrayList<>();
|
// this.unprocessedEntries = new ArrayList<>();
|
||||||
validEntries = ArrayList()
|
//validEntries = ArrayList()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -67,13 +67,13 @@ class PumpMessage : RLMessage {
|
||||||
|
|
||||||
override fun getTxData(): ByteArray {
|
override fun getTxData(): ByteArray {
|
||||||
var rval = ByteUtil.concat(byteArrayOf(packetType!!.value), address)
|
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)
|
rval = ByteUtil.concat(rval, messageBody!!.txData)
|
||||||
return rval
|
return rval
|
||||||
}
|
}
|
||||||
|
|
||||||
val contents: ByteArray
|
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
|
// data, after length
|
||||||
|
|
||||||
// check if displayed length is invalid
|
// check if displayed length is invalid
|
||||||
|
@ -91,7 +91,7 @@ class PumpMessage : RLMessage {
|
||||||
val data = messageBody!!.txData
|
val data = messageBody!!.txData
|
||||||
var length = ByteUtil.asUINT8(data!![0]) // length is not always correct so, we check whole array if we have
|
var length = ByteUtil.asUINT8(data!![0]) // length is not always correct so, we check whole array if we have
|
||||||
// data, after length
|
// data, after length
|
||||||
val originalLength = length
|
//val originalLength = length
|
||||||
|
|
||||||
// check if displayed length is invalid
|
// check if displayed length is invalid
|
||||||
if (length > data.size - 1) {
|
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) {
|
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) {
|
private void processTDDs(List<PumpHistoryEntry> tddsIn) {
|
||||||
|
@ -972,7 +973,7 @@ public class MedtronicHistoryData {
|
||||||
|
|
||||||
detailedBolusInfo.setBolusTimestamp(tryToGetByLocalTime(bolus.getAtechDateTime()));
|
detailedBolusInfo.setBolusTimestamp(tryToGetByLocalTime(bolus.getAtechDateTime()));
|
||||||
detailedBolusInfo.setPumpType(PumpType.MEDTRONIC_512_712); // TODO grab real model
|
detailedBolusInfo.setPumpType(PumpType.MEDTRONIC_512_712); // TODO grab real model
|
||||||
detailedBolusInfo.setPumpSerial(medtronicPumpStatus.serialNumber);
|
detailedBolusInfo.setPumpSerial(medtronicPumpStatus.getSerialNumber());
|
||||||
detailedBolusInfo.setBolusPumpId(bolus.getPumpId());
|
detailedBolusInfo.setBolusPumpId(bolus.getPumpId());
|
||||||
detailedBolusInfo.insulin = bolusDTO.getDeliveredAmount();
|
detailedBolusInfo.insulin = bolusDTO.getDeliveredAmount();
|
||||||
|
|
||||||
|
@ -1046,7 +1047,7 @@ public class MedtronicHistoryData {
|
||||||
if (doubleBolusDebug)
|
if (doubleBolusDebug)
|
||||||
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: addCarbsFromEstimate: Bolus=%s, BolusWizardDTO=%s", bolus, bolusWizard));
|
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
|
// 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,
|
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();
|
return minutes.getMinutes();
|
||||||
}
|
}
|
||||||
|
@ -1480,7 +1481,7 @@ public class MedtronicHistoryData {
|
||||||
aapsLogger.debug(LTag.PUMP, "processLastBasalProfileChange. item found, setting new basalProfileLocally: " + newProfile);
|
aapsLogger.debug(LTag.PUMP, "processLastBasalProfileChange. item found, setting new basalProfileLocally: " + newProfile);
|
||||||
BasalProfile basalProfile = (BasalProfile) newProfile.getDecodedData().get("Object");
|
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 {
|
private fun setRawData(data: ByteArray): Boolean {
|
||||||
var data: ByteArray? = data
|
var dataInternal: ByteArray? = data
|
||||||
if (data == null) {
|
if (dataInternal == null) {
|
||||||
aapsLogger.error(LTag.PUMPCOMM, "setRawData: buffer is null!")
|
aapsLogger.error(LTag.PUMPCOMM, "setRawData: buffer is null!")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have just one entry through all day it looks like just length 1
|
// if we have just one entry through all day it looks like just length 1
|
||||||
if (data.size == 1) {
|
if (dataInternal.size == 1) {
|
||||||
data = MedtronicUtil.createByteArray(data[0], 0.toByte(), 0.toByte())
|
dataInternal = byteArrayOf(dataInternal[0], 0, 0)
|
||||||
}
|
}
|
||||||
if (data!!.size == MAX_RAW_DATA_SIZE) {
|
if (dataInternal.size == MAX_RAW_DATA_SIZE) {
|
||||||
rawData = data
|
rawData = dataInternal
|
||||||
} else {
|
} else {
|
||||||
val len = Math.min(MAX_RAW_DATA_SIZE, data.size)
|
val len = Math.min(MAX_RAW_DATA_SIZE, data.size)
|
||||||
rawData = ByteArray(MAX_RAW_DATA_SIZE)
|
rawData = ByteArray(MAX_RAW_DATA_SIZE)
|
||||||
|
@ -233,10 +233,10 @@ class BasalProfile {
|
||||||
// return this.mRawData;
|
// return this.mRawData;
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getProfilesByHour(pumpType: PumpType?): Array<Double?> {
|
fun getProfilesByHour(pumpType: PumpType): Array<Double> {
|
||||||
var entries: List<BasalProfileEntry>? = null
|
var entriesCopy: List<BasalProfileEntry>? = null
|
||||||
try {
|
try {
|
||||||
entries = entries
|
entriesCopy = entries
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
aapsLogger.error(LTag.PUMPCOMM, "=============================================================================")
|
aapsLogger.error(LTag.PUMPCOMM, "=============================================================================")
|
||||||
aapsLogger.error(LTag.PUMPCOMM, " Error generating entries. Ex.: $ex", ex)
|
aapsLogger.error(LTag.PUMPCOMM, " Error generating entries. Ex.: $ex", ex)
|
||||||
|
@ -245,40 +245,43 @@ class BasalProfile {
|
||||||
|
|
||||||
//FabricUtil.createEvent("MedtronicBasalProfileGetByHourError", null);
|
//FabricUtil.createEvent("MedtronicBasalProfileGetByHourError", null);
|
||||||
}
|
}
|
||||||
if (entries == null || entries.size == 0) {
|
if (entriesCopy == null || entriesCopy.size == 0) {
|
||||||
val basalByHour = arrayOfNulls<Double>(24)
|
val basalByHour = arrayOfNulls<Double>(24)
|
||||||
for (i in 0..23) {
|
for (i in 0..23) {
|
||||||
basalByHour[i] = 0.0
|
basalByHour[i] = 0.0
|
||||||
}
|
}
|
||||||
return basalByHour
|
return basalByHour as Array<Double>
|
||||||
}
|
}
|
||||||
val basalByHour = arrayOfNulls<Double>(24)
|
val basalByHour = arrayOfNulls<Double>(24)
|
||||||
for (i in entries.indices) {
|
for (i in entriesCopy.indices) {
|
||||||
val current = entries[i]
|
val current = entriesCopy[i]
|
||||||
var currentTime = if (current.startTime_raw % 2 == 0) current.startTime_raw.toInt() else current.startTime_raw - 1
|
var currentTime = if (current.startTime_raw % 2 == 0) current.startTime_raw.toInt() else current.startTime_raw - 1
|
||||||
currentTime = currentTime * 30 / 60
|
currentTime = currentTime * 30 / 60
|
||||||
var lastHour: Int
|
var lastHour: Int
|
||||||
lastHour = if (i + 1 == entries.size) {
|
lastHour = if (i + 1 == entriesCopy.size) {
|
||||||
24
|
24
|
||||||
} else {
|
} 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
|
val rawTime = if (basalProfileEntry.startTime_raw % 2 == 0) basalProfileEntry.startTime_raw.toInt() else basalProfileEntry.startTime_raw - 1
|
||||||
rawTime * 30 / 60
|
rawTime * 30 / 60
|
||||||
}
|
}
|
||||||
|
|
||||||
// System.out.println("Current time: " + currentTime + " Next Time: " + lastHour);
|
// System.out.println("Current time: " + currentTime + " Next Time: " + lastHour);
|
||||||
for (j in currentTime until 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 {
|
override fun toString(): String {
|
||||||
return basalProfileToString()
|
return basalProfileToString()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun verify(pumpType: PumpType?): Boolean {
|
fun verify(pumpType: PumpType): Boolean {
|
||||||
try {
|
try {
|
||||||
entries
|
entries
|
||||||
} catch (ex: Exception) {
|
} 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">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_history_request">Get History - Page %1$d</string>
|
||||||
<string name="medtronic_cmd_desc_get_time">Get Pump Time</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_settings">Get Settings</string>
|
||||||
<string name="medtronic_cmd_desc_get_model">Get Pump Model</string>
|
<string name="medtronic_cmd_desc_get_model">Get Pump Model</string>
|
||||||
<string name="medtronic_cmd_desc_get_basal_profile">Get Basal Profile</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="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_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="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>
|
<string name="sixdigitnumber" translatable="false">^\\d{6}</string>
|
||||||
|
|
||||||
</resources>
|
</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) {
|
public static List<Byte> getListFromByteArray(byte[] array) {
|
||||||
List<Byte> listOut = new ArrayList<Byte>();
|
List<Byte> listOut = new ArrayList<Byte>();
|
||||||
|
|
||||||
|
@ -340,6 +324,9 @@ public class ByteUtil {
|
||||||
return toInt(b1, b2, b3, null, BitConversion.BIG_ENDIAN);
|
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) {
|
public static int toInt(int b1, int b2, BitConversion flag) {
|
||||||
return toInt(b1, b2, null, null, flag);
|
return toInt(b1, b2, null, null, flag);
|
||||||
|
|
Loading…
Reference in a new issue