Medtronic 0.5
- added DailyTotalsDTO and started with work on parsing (522 done) - split encoding into 3 classes, and added exception when encoding fails - added code for retries, when in communication with pump - added analysis of history data for several occassions (profile changed, configuration changed, etc) - little refactoring all arround
This commit is contained in:
parent
3fdbc0400e
commit
adc80d5cc7
|
@ -7,18 +7,20 @@
|
|||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- daily rollover. Make sure the path matches the one in the file element or else
|
||||
the rollover logs are placed in the working directory. -->
|
||||
<fileNamePattern>${EXT_FILES_DIR}/AndroidAPS._%d{yyyy-MM-dd}_%d{HH-mm-ss, aux}_.%i.zip
|
||||
<fileNamePattern>${EXT_FILES_DIR}/AndroidAPS._%d{yyyy-MM-dd}_%d{HH-mm}_.%i.zip
|
||||
</fileNamePattern>
|
||||
|
||||
<timeBasedFileNamingAndTriggeringPolicy
|
||||
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>5MB</maxFileSize>
|
||||
<maxFileSize>500KB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!-- keep 30 days' worth of history -->
|
||||
<maxHistory>120</maxHistory>
|
||||
<maxHistory>240</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %.-1level/%logger: [%class{0}.%M\(\):%line]: %msg%n</pattern>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %.-1level/%logger: [%class{0}.%M\(\):%line]:
|
||||
%msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import info.nightscout.androidaps.interfaces.PluginBase;
|
|||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.data.PumpStatus;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpDriverState;
|
||||
|
@ -141,40 +142,40 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
|
||||
|
||||
public boolean isConnected() {
|
||||
if (displayConnectionMessages)
|
||||
if (displayConnectionMessages && isLoggingEnabled())
|
||||
LOG.warn("isConnected [PumpPluginAbstract].");
|
||||
return PumpDriverState.isConnected(pumpState);
|
||||
}
|
||||
|
||||
|
||||
public boolean isConnecting() {
|
||||
if (displayConnectionMessages)
|
||||
if (displayConnectionMessages && isLoggingEnabled())
|
||||
LOG.warn("isConnecting [PumpPluginAbstract].");
|
||||
return pumpState == PumpDriverState.Connecting;
|
||||
}
|
||||
|
||||
|
||||
public void connect(String reason) {
|
||||
if (displayConnectionMessages)
|
||||
if (displayConnectionMessages && isLoggingEnabled())
|
||||
LOG.warn("connect (reason={}) [PumpPluginAbstract] - default (empty) implementation.", reason);
|
||||
}
|
||||
|
||||
|
||||
public void disconnect(String reason) {
|
||||
if (displayConnectionMessages)
|
||||
if (displayConnectionMessages && isLoggingEnabled())
|
||||
LOG.warn("disconnect (reason={}) [PumpPluginAbstract] - default (empty) implementation.", reason);
|
||||
}
|
||||
|
||||
|
||||
public void stopConnecting() {
|
||||
if (displayConnectionMessages)
|
||||
if (displayConnectionMessages && isLoggingEnabled())
|
||||
LOG.warn("stopConnecting [PumpPluginAbstract] - default (empty) implementation.");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isHandshakeInProgress() {
|
||||
if (displayConnectionMessages)
|
||||
if (displayConnectionMessages && isLoggingEnabled())
|
||||
LOG.warn("isHandshakeInProgress [PumpPluginAbstract] - default (empty) implementation.");
|
||||
return false;
|
||||
}
|
||||
|
@ -182,50 +183,57 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
|
||||
@Override
|
||||
public void finishHandshaking() {
|
||||
if (displayConnectionMessages)
|
||||
if (displayConnectionMessages && isLoggingEnabled())
|
||||
LOG.warn("finishHandshaking [PumpPluginAbstract] - default (empty) implementation.");
|
||||
}
|
||||
|
||||
|
||||
public void getPumpStatus() {
|
||||
LOG.warn("getPumpStatus [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("getPumpStatus [PumpPluginAbstract] - Not implemented.");
|
||||
}
|
||||
|
||||
|
||||
// Upload to pump new basal profile
|
||||
public PumpEnactResult setNewBasalProfile(Profile profile) {
|
||||
LOG.warn("setNewBasalProfile [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("setNewBasalProfile [PumpPluginAbstract] - Not implemented.");
|
||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
||||
}
|
||||
|
||||
|
||||
public boolean isThisProfileSet(Profile profile) {
|
||||
LOG.warn("isThisProfileSet [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("isThisProfileSet [PumpPluginAbstract] - Not implemented.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public long lastDataTime() {
|
||||
LOG.warn("lastDataTime [PumpPluginAbstract].");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("lastDataTime [PumpPluginAbstract].");
|
||||
return pumpStatus.lastConnection;
|
||||
}
|
||||
|
||||
|
||||
public double getBaseBasalRate() {
|
||||
LOG.warn("getBaseBasalRate [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("getBaseBasalRate [PumpPluginAbstract] - Not implemented.");
|
||||
return 0.0d;
|
||||
} // base basal rate, not temp basal
|
||||
|
||||
|
||||
public void stopBolusDelivering() {
|
||||
LOG.warn("stopBolusDelivering [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("stopBolusDelivering [PumpPluginAbstract] - Not implemented.");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile,
|
||||
boolean enforceNew) {
|
||||
LOG.warn("setTempBasalAbsolute [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("setTempBasalAbsolute [PumpPluginAbstract] - Not implemented.");
|
||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
||||
}
|
||||
|
||||
|
@ -233,13 +241,15 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile,
|
||||
boolean enforceNew) {
|
||||
LOG.warn("setTempBasalPercent [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("setTempBasalPercent [PumpPluginAbstract] - Not implemented.");
|
||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
||||
}
|
||||
|
||||
|
||||
public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
|
||||
LOG.warn("setExtendedBolus [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("setExtendedBolus [PumpPluginAbstract] - Not implemented.");
|
||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
||||
}
|
||||
|
||||
|
@ -248,13 +258,15 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
// when the cancel request is requested by the user (forced), the pump should always do a real cancel
|
||||
|
||||
public PumpEnactResult cancelTempBasal(boolean enforceNew) {
|
||||
LOG.warn("cancelTempBasal [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("cancelTempBasal [PumpPluginAbstract] - Not implemented.");
|
||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
||||
}
|
||||
|
||||
|
||||
public PumpEnactResult cancelExtendedBolus() {
|
||||
LOG.warn("cancelExtendedBolus [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("cancelExtendedBolus [PumpPluginAbstract] - Not implemented.");
|
||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
||||
}
|
||||
|
||||
|
@ -266,7 +278,8 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
// }
|
||||
|
||||
public String deviceID() {
|
||||
LOG.warn("deviceID [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("deviceID [PumpPluginAbstract] - Not implemented.");
|
||||
return "FakeDevice";
|
||||
}
|
||||
|
||||
|
@ -281,14 +294,16 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
// Short info for SMS, Wear etc
|
||||
|
||||
public boolean isFakingTempsByExtendedBoluses() {
|
||||
LOG.warn("isFakingTempsByExtendedBoluses [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("isFakingTempsByExtendedBoluses [PumpPluginAbstract] - Not implemented.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PumpEnactResult loadTDDs() {
|
||||
LOG.warn("loadTDDs [PumpPluginAbstract] - Not implemented.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("loadTDDs [PumpPluginAbstract] - Not implemented.");
|
||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
||||
}
|
||||
|
||||
|
@ -383,7 +398,8 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
try {
|
||||
if (detailedBolusInfo.insulin == 0 && detailedBolusInfo.carbs == 0) {
|
||||
// neither carbs nor bolus requested
|
||||
LOG.error("deliverTreatment: Invalid input");
|
||||
if (isLoggingEnabled())
|
||||
LOG.error("deliverTreatment: Invalid input");
|
||||
return new PumpEnactResult().success(false).enacted(false).bolusDelivered(0d).carbsDelivered(0d)
|
||||
.comment(MainApp.gs(R.string.danar_invalidinput));
|
||||
} else if (detailedBolusInfo.insulin > 0) {
|
||||
|
@ -399,7 +415,8 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
bolusingEvent.percent = 100;
|
||||
MainApp.bus().post(bolusingEvent);
|
||||
|
||||
LOG.debug("deliverTreatment: Carb only treatment.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("deliverTreatment: Carb only treatment.");
|
||||
|
||||
return new PumpEnactResult().success(true).enacted(true).bolusDelivered(0d)
|
||||
.carbsDelivered(detailedBolusInfo.carbs).comment(MainApp.gs(R.string.virtualpump_resultok));
|
||||
|
@ -411,6 +428,11 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
}
|
||||
|
||||
|
||||
public boolean isLoggingEnabled() {
|
||||
return L.isEnabled(L.PUMP);
|
||||
}
|
||||
|
||||
|
||||
protected abstract PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo);
|
||||
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.content.Context;
|
|||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.data.PumpStatus;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RFSpy;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkCommunicationException;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.FrequencyScanResults;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.FrequencyTrial;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.RFSpyResponse;
|
||||
|
@ -14,7 +15,7 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.RLMes
|
|||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.RadioPacket;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.RadioResponse;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RLMessageType;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkTargetFrequency;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkBLEError;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.RileyLinkServiceData;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.ServiceTaskExecutor;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.WakeAndTuneTask;
|
||||
|
@ -42,9 +43,9 @@ public abstract class RileyLinkCommunicationManager {
|
|||
protected long lastGoodReceiverCommunicationTime = 0;
|
||||
protected PumpStatus pumpStatus;
|
||||
protected RileyLinkServiceData rileyLinkServiceData;
|
||||
protected RileyLinkTargetFrequency targetFrequency;
|
||||
// protected RileyLinkTargetFrequency targetFrequency;
|
||||
private long nextWakeUpRequired = 0L;
|
||||
private double[] scanFrequencies;
|
||||
// private double[] scanFrequencies;
|
||||
|
||||
// internal flag
|
||||
private boolean showPumpMessages = true;
|
||||
|
@ -54,8 +55,8 @@ public abstract class RileyLinkCommunicationManager {
|
|||
public RileyLinkCommunicationManager(Context context, RFSpy rfspy) {
|
||||
this.context = context;
|
||||
this.rfspy = rfspy;
|
||||
this.targetFrequency = RileyLinkUtil.getRileyLinkTargetFrequency();
|
||||
this.scanFrequencies = targetFrequency.getScanFrequencies();
|
||||
// this.targetFrequency = RileyLinkUtil.getRileyLinkTargetFrequency();
|
||||
// this.scanFrequencies = targetFrequency.getScanFrequencies();
|
||||
this.rileyLinkServiceData = RileyLinkUtil.getRileyLinkServiceData();
|
||||
RileyLinkUtil.setRileyLinkCommunicationManager(this);
|
||||
|
||||
|
@ -66,17 +67,17 @@ public abstract class RileyLinkCommunicationManager {
|
|||
protected abstract void configurePumpSpecificSettings();
|
||||
|
||||
|
||||
public void refreshRileyLinkTargetFrequency() {
|
||||
if (this.targetFrequency != RileyLinkUtil.getRileyLinkTargetFrequency()) {
|
||||
this.targetFrequency = RileyLinkUtil.getRileyLinkTargetFrequency();
|
||||
this.scanFrequencies = targetFrequency.getScanFrequencies();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// public void refreshRileyLinkTargetFrequency() {
|
||||
// if (this.targetFrequency != RileyLinkUtil.getRileyLinkTargetFrequency()) {
|
||||
// this.targetFrequency = RileyLinkUtil.getRileyLinkTargetFrequency();
|
||||
// this.scanFrequencies = targetFrequency.getScanFrequencies();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
// All pump communications go through this function.
|
||||
protected <E extends RLMessage> E sendAndListen(RLMessage msg, int timeout_ms, Class<E> clazz) {
|
||||
protected <E extends RLMessage> E sendAndListen(RLMessage msg, int timeout_ms, Class<E> clazz)
|
||||
throws RileyLinkCommunicationException {
|
||||
|
||||
if (showPumpMessages) {
|
||||
LOG.info("Sent:" + ByteUtil.shortHexString(msg.getTxData()));
|
||||
|
@ -84,6 +85,8 @@ public abstract class RileyLinkCommunicationManager {
|
|||
|
||||
RFSpyResponse rfSpyResponse = rfspy.transmitThenReceive(new RadioPacket(msg.getTxData()), timeout_ms);
|
||||
|
||||
RadioResponse radioResponse = rfSpyResponse.getRadioResponse();
|
||||
|
||||
E response = createResponseMessage(rfSpyResponse.getRadioResponse().getPayload(), clazz);
|
||||
|
||||
if (response.isValid()) {
|
||||
|
@ -103,6 +106,10 @@ public abstract class RileyLinkCommunicationManager {
|
|||
ServiceTaskExecutor.startTask(new WakeAndTuneTask());
|
||||
timeoutCount = 0;
|
||||
}
|
||||
|
||||
throw new RileyLinkCommunicationException(RileyLinkBLEError.Timeout);
|
||||
} else if (rfSpyResponse.wasInterrupted()) {
|
||||
throw new RileyLinkCommunicationException(RileyLinkBLEError.Interrupted);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,18 +134,17 @@ public abstract class RileyLinkCommunicationManager {
|
|||
}
|
||||
|
||||
|
||||
public boolean changeTargetFrequency(RileyLinkTargetFrequency targetFrequency) {
|
||||
|
||||
if (this.targetFrequency == targetFrequency) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.targetFrequency = targetFrequency;
|
||||
this.scanFrequencies = targetFrequency.getScanFrequencies();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// public boolean changeTargetFrequency(RileyLinkTargetFrequency targetFrequency) {
|
||||
//
|
||||
// if (this.targetFrequency == targetFrequency) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// this.targetFrequency = targetFrequency;
|
||||
// this.scanFrequencies = targetFrequency.getScanFrequencies();
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// FIXME change wakeup
|
||||
// TODO we might need to fix this. Maybe make pump awake for shorter time (battery factor for pump) - Andy
|
||||
|
@ -188,7 +194,7 @@ public abstract class RileyLinkCommunicationManager {
|
|||
|
||||
|
||||
public double tuneForDevice() {
|
||||
return scanForDevice(scanFrequencies);
|
||||
return scanForDevice(RileyLinkUtil.getRileyLinkTargetFrequency().getScanFrequencies());
|
||||
}
|
||||
|
||||
|
||||
|
@ -201,10 +207,13 @@ public abstract class RileyLinkCommunicationManager {
|
|||
* @return
|
||||
*/
|
||||
public boolean isValidFrequency(double frequency) {
|
||||
|
||||
double[] scanFrequencies = RileyLinkUtil.getRileyLinkTargetFrequency().getScanFrequencies();
|
||||
|
||||
if (scanFrequencies.length == 1) {
|
||||
return RileyLinkUtil.isSame(scanFrequencies[0], frequency);
|
||||
} else {
|
||||
return (this.scanFrequencies[0] <= frequency && this.scanFrequencies[scanFrequencies.length - 1] >= frequency);
|
||||
return (scanFrequencies[0] <= frequency && scanFrequencies[scanFrequencies.length - 1] >= frequency);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,15 +247,26 @@ public abstract class RileyLinkCommunicationManager {
|
|||
if (resp.wasTimeout()) {
|
||||
LOG.error("scanForPump: Failed to find pump at frequency {}", frequencies[i]);
|
||||
} else if (resp.looksLikeRadioPacket()) {
|
||||
RadioResponse radioResponse = new RadioResponse(resp.getRaw());
|
||||
if (radioResponse.isValid()) {
|
||||
sumRSSI += radioResponse.rssi;
|
||||
trial.rssiList.add(radioResponse.rssi);
|
||||
trial.successes++;
|
||||
} else {
|
||||
LOG.warn("Failed to parse radio response: " + ByteUtil.shortHexString(resp.getRaw()));
|
||||
RadioResponse radioResponse = new RadioResponse();
|
||||
|
||||
try {
|
||||
|
||||
radioResponse.init(resp.getRaw());
|
||||
|
||||
if (radioResponse.isValid()) {
|
||||
sumRSSI += radioResponse.rssi;
|
||||
trial.rssiList.add(radioResponse.rssi);
|
||||
trial.successes++;
|
||||
} else {
|
||||
LOG.warn("Failed to parse radio response: " + ByteUtil.shortHexString(resp.getRaw()));
|
||||
trial.rssiList.add(-99);
|
||||
}
|
||||
|
||||
} catch (RileyLinkCommunicationException rle) {
|
||||
LOG.warn("Failed to decode radio response: " + ByteUtil.shortHexString(resp.getRaw()));
|
||||
trial.rssiList.add(-99);
|
||||
}
|
||||
|
||||
} else {
|
||||
LOG.error("scanForPump: raw response is " + ByteUtil.shortHexString(resp.getRaw()));
|
||||
trial.rssiList.add(-99);
|
||||
|
@ -302,15 +322,23 @@ public abstract class RileyLinkCommunicationManager {
|
|||
if (resp.wasTimeout()) {
|
||||
LOG.warn("tune_tryFrequency: no pump response at frequency {}", freqMHz);
|
||||
} else if (resp.looksLikeRadioPacket()) {
|
||||
RadioResponse radioResponse = new RadioResponse(resp.getRaw());
|
||||
if (radioResponse.isValid()) {
|
||||
LOG.warn("tune_tryFrequency: saw response level {} at frequency {}", radioResponse.rssi, freqMHz);
|
||||
return radioResponse.rssi;
|
||||
} else {
|
||||
LOG.warn("tune_tryFrequency: invalid radio response:"
|
||||
+ ByteUtil.shortHexString(radioResponse.getPayload()));
|
||||
RadioResponse radioResponse = new RadioResponse();
|
||||
try {
|
||||
radioResponse.init(resp.getRaw());
|
||||
|
||||
if (radioResponse.isValid()) {
|
||||
LOG.warn("tune_tryFrequency: saw response level {} at frequency {}", radioResponse.rssi, freqMHz);
|
||||
return radioResponse.rssi;
|
||||
} else {
|
||||
LOG.warn("tune_tryFrequency: invalid radio response:"
|
||||
+ ByteUtil.shortHexString(radioResponse.getPayload()));
|
||||
}
|
||||
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
LOG.warn("Failed to decode radio response: " + ByteUtil.shortHexString(resp.getRaw()));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ public class RileyLinkConst {
|
|||
|
||||
public static final String RileyLinkReady = Prefix + "RileyLink_Ready";
|
||||
public static final String RileyLinkGattFailed = Prefix + "RileyLink_Gatt_Failed";
|
||||
// public static final String RileyLinkError = Prefix + "RileyLink_Ready";
|
||||
// public static final String RileyLinkBLEError = Prefix + "RileyLink_Ready";
|
||||
|
||||
public static final String BluetoothConnected = Prefix + "Bluetooth_Connected";
|
||||
public static final String BluetoothReconnected = Prefix + "Bluetooth_Reconnected";
|
||||
|
|
|
@ -16,6 +16,8 @@ import android.support.v4.content.LocalBroadcastManager;
|
|||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkBLE;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.encoding.Encoding4b6b;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.encoding.Encoding4b6bGeoff;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkEncodingType;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkTargetFrequency;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.data.BleAdvertisedData;
|
||||
|
@ -59,6 +61,7 @@ public class RileyLinkUtil {
|
|||
private static RileyLinkTargetDevice targetDevice;
|
||||
private static RileyLinkEncodingType encoding;
|
||||
private static RileyLinkSelectPreference rileyLinkSelectPreference;
|
||||
private static Encoding4b6b encoding4b6b;
|
||||
|
||||
|
||||
public static void setContext(Context contextIn) {
|
||||
|
@ -74,6 +77,10 @@ public class RileyLinkUtil {
|
|||
|
||||
public static void setEncoding(RileyLinkEncodingType encoding) {
|
||||
RileyLinkUtil.encoding = encoding;
|
||||
|
||||
if (encoding == RileyLinkEncodingType.FourByteSixByte) {
|
||||
RileyLinkUtil.encoding4b6b = new Encoding4b6bGeoff();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -316,4 +323,8 @@ public class RileyLinkUtil {
|
|||
return rileyLinkSelectPreference;
|
||||
}
|
||||
|
||||
|
||||
public static Encoding4b6b getEncoding4b6b() {
|
||||
return RileyLinkUtil.encoding4b6b;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ import info.nightscout.androidaps.plugins.PumpCommon.utils.ThreadUtil;
|
|||
*/
|
||||
public class RileyLinkBLE {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RFTools.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RileyLinkBLE.class);
|
||||
|
||||
private final Context context;
|
||||
public boolean gattDebugEnabled = true;
|
||||
boolean manualDisconnect = false;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkBLEError;
|
||||
|
||||
/**
|
||||
* Created by andy on 11/23/18.
|
||||
*/
|
||||
|
||||
public class RileyLinkCommunicationException extends Throwable {
|
||||
|
||||
String extendedErrorText;
|
||||
private RileyLinkBLEError errorCode;
|
||||
|
||||
|
||||
public RileyLinkCommunicationException(RileyLinkBLEError errorCode, String extendedErrorText) {
|
||||
super(errorCode.getDescription());
|
||||
|
||||
this.errorCode = errorCode;
|
||||
this.extendedErrorText = extendedErrorText;
|
||||
}
|
||||
|
||||
|
||||
public RileyLinkCommunicationException(RileyLinkBLEError errorCode) {
|
||||
super(errorCode.getDescription());
|
||||
|
||||
this.errorCode = errorCode;
|
||||
// this.extendedErrorText = extendedErrorText;
|
||||
}
|
||||
|
||||
}
|
|
@ -87,7 +87,7 @@ public class SendAndListen extends RileyLinkCommand {
|
|||
bytes.add(preambleBuf[3]);
|
||||
}
|
||||
|
||||
return ByteUtil.concat(ByteUtil.fromByteArray(bytes), packetToSend.getEncoded());
|
||||
return ByteUtil.concat(ByteUtil.getByteArrayFromList(bytes), packetToSend.getEncoded());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkCommunicationException;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.command.RileyLinkCommand;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RFSpyRLResponse;
|
||||
|
||||
|
@ -47,9 +48,10 @@ public class RFSpyResponse {
|
|||
}
|
||||
|
||||
|
||||
public RadioResponse getRadioResponse() {
|
||||
public RadioResponse getRadioResponse() throws RileyLinkCommunicationException {
|
||||
if (looksLikeRadioPacket()) {
|
||||
radioResponse = new RadioResponse(command, raw);
|
||||
radioResponse = new RadioResponse(command);
|
||||
radioResponse.init(raw);
|
||||
} else {
|
||||
radioResponse = new RadioResponse();
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data;
|
|||
import org.apache.commons.lang3.NotImplementedException;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkUtil;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RFTools;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.CRC;
|
||||
|
||||
|
@ -42,7 +41,7 @@ public class RadioPacket {
|
|||
case FourByteSixByte: {
|
||||
byte[] withCRC = getWithCRC();
|
||||
|
||||
byte[] encoded = RFTools.encode4b6b(withCRC);
|
||||
byte[] encoded = RileyLinkUtil.getEncoding4b6b().encode4b6b(withCRC);
|
||||
return ByteUtil.concat(encoded, (byte)0);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,13 +5,12 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkUtil;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RFTools;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkCommunicationException;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.command.RileyLinkCommand;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkCommandType;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkFirmwareVersion;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.CRC;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.FabricUtil;
|
||||
|
||||
/**
|
||||
* Created by geoff on 5/30/16.
|
||||
|
@ -33,14 +32,13 @@ public class RadioResponse {
|
|||
}
|
||||
|
||||
|
||||
public RadioResponse(byte[] rxData) {
|
||||
init(rxData);
|
||||
}
|
||||
// public RadioResponse(byte[] rxData) {
|
||||
// init(rxData);
|
||||
// }
|
||||
|
||||
|
||||
public RadioResponse(RileyLinkCommand command, byte[] raw) {
|
||||
public RadioResponse(RileyLinkCommand command /* , byte[] raw */) {
|
||||
this.command = command;
|
||||
init(raw);
|
||||
// init(raw);
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,7 +61,7 @@ public class RadioResponse {
|
|||
}
|
||||
|
||||
|
||||
public void init(byte[] rxData) {
|
||||
public void init(byte[] rxData) throws RileyLinkCommunicationException {
|
||||
|
||||
if (rxData == null) {
|
||||
return;
|
||||
|
@ -101,23 +99,9 @@ public class RadioResponse {
|
|||
decodedPayload = encodedPayload;
|
||||
break;
|
||||
case FourByteSixByte:
|
||||
RFTools.DecodeResponseDto decodeResponseDto = RFTools.decode4b6bWithoutException(encodedPayload);
|
||||
byte[] decodeThis = decodeResponseDto.data;
|
||||
byte[] decodeThis = RileyLinkUtil.getEncoding4b6b().decode4b6b(encodedPayload);
|
||||
decodedOK = true;
|
||||
|
||||
if (decodeThis == null || decodeThis.length == 0 || decodeResponseDto.errorData != null) {
|
||||
LOG.error("=============================================================================");
|
||||
LOG.error(" Decoded payload length is zero.");
|
||||
LOG.error(" encodedPayload: {}", ByteUtil.getHex(encodedPayload));
|
||||
LOG.error(" errors: {}", decodeResponseDto.errorData);
|
||||
LOG.error("=============================================================================");
|
||||
|
||||
FabricUtil.createEvent("MedtronicDecode4b6bError", null);
|
||||
|
||||
decodedOK = false;
|
||||
return;
|
||||
}
|
||||
|
||||
decodedPayload = ByteUtil.substring(decodeThis, 0, decodeThis.length - 1);
|
||||
receivedCRC = decodeThis[decodeThis.length - 1];
|
||||
byte calculatedCRC = CRC.crc8(decodedPayload);
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.encoding;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkCommunicationException;
|
||||
|
||||
/**
|
||||
* Created by andy on 11/24/18.
|
||||
*/
|
||||
|
||||
public interface Encoding4b6b {
|
||||
|
||||
byte[] encode4b6b(byte[] data);
|
||||
|
||||
|
||||
byte[] decode4b6b(byte[] data) throws RileyLinkCommunicationException;
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.encoding;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkCommunicationException;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.FabricUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 11/24/18.
|
||||
*/
|
||||
|
||||
public abstract class Encoding4b6bAbstract implements Encoding4b6b {
|
||||
|
||||
/**
|
||||
* encode4b6bMap is an ordered list of translations 6bits -> 4 bits, in order from 0x0 to 0xF
|
||||
* The 6 bit codes are what is used on the RF side of the RileyLink to communicate
|
||||
* with a Medtronic pump.
|
||||
*/
|
||||
public static final byte[] encode4b6bList = new byte[] {
|
||||
0x15, 0x31, 0x32, 0x23, 0x34, 0x25, 0x26, 0x16, 0x1a, 0x19, 0x2a, 0x0b, 0x2c, 0x0d, 0x0e, 0x1c };
|
||||
|
||||
|
||||
// 21, 49, 50, 35, 52, 37, 38, 22, 26, 25, 42, 11, 44, 13, 14, 28
|
||||
|
||||
public abstract byte[] encode4b6b(byte[] data);
|
||||
|
||||
|
||||
public abstract byte[] decode4b6b(byte[] data) throws RileyLinkCommunicationException;
|
||||
|
||||
|
||||
protected short convertUnsigned(byte x) {
|
||||
short ss = x;
|
||||
|
||||
if (ss < 0) {
|
||||
ss += 256;
|
||||
}
|
||||
|
||||
return ss;
|
||||
}
|
||||
|
||||
|
||||
/* O(n) lookup. Run on an O(n) translation of a byte-stream, gives O(n**2) performance. Sigh. */
|
||||
public static int encode4b6bListIndex(byte b) {
|
||||
for (int i = 0; i < encode4b6bList.length; i++) {
|
||||
if (b == encode4b6bList[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public void writeError(Logger LOG, byte[] raw, String errorData) {
|
||||
|
||||
LOG.error("=============================================================================");
|
||||
LOG.error(" Decoded payload length is zero.");
|
||||
LOG.error(" encodedPayload: {}", ByteUtil.getHex(raw));
|
||||
LOG.error(" errors: {}", errorData);
|
||||
LOG.error("=============================================================================");
|
||||
|
||||
FabricUtil.createEvent("MedtronicDecode4b6bError", null);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,249 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.encoding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkCommunicationException;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkBLEError;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 11/24/18.
|
||||
*/
|
||||
|
||||
public class Encoding4b6bGeoff extends Encoding4b6bAbstract {
|
||||
|
||||
public static final Logger LOG = LoggerFactory.getLogger(Encoding4b6bGeoff.class);
|
||||
|
||||
|
||||
public byte[] encode4b6b(byte[] data) {
|
||||
// if ((data.length % 2) != 0) {
|
||||
// LOG.error("Warning: data is odd number of bytes");
|
||||
// }
|
||||
// use arraylists because byte[] is annoying.
|
||||
List<Byte> inData = ByteUtil.getListFromByteArray(data);
|
||||
List<Byte> outData = new ArrayList<>();
|
||||
|
||||
int acc = 0;
|
||||
int bitcount = 0;
|
||||
int i;
|
||||
for (i = 0; i < inData.size(); i++) {
|
||||
acc <<= 6;
|
||||
acc |= encode4b6bList[(inData.get(i) >> 4) & 0x0f];
|
||||
bitcount += 6;
|
||||
|
||||
acc <<= 6;
|
||||
acc |= encode4b6bList[inData.get(i) & 0x0f];
|
||||
bitcount += 6;
|
||||
|
||||
while (bitcount >= 8) {
|
||||
byte outByte = (byte)(acc >> (bitcount - 8) & 0xff);
|
||||
outData.add(outByte);
|
||||
bitcount -= 8;
|
||||
acc &= (0xffff >> (16 - bitcount));
|
||||
}
|
||||
}
|
||||
if (bitcount > 0) {
|
||||
acc <<= 6;
|
||||
acc |= 0x14; // marks uneven packet boundary.
|
||||
bitcount += 6;
|
||||
if (bitcount >= 8) {
|
||||
byte outByte = (byte)((acc >> (bitcount - 8)) & 0xff);
|
||||
outData.add(outByte);
|
||||
bitcount -= 8;
|
||||
// acc &= (0xffff >> (16 - bitcount));
|
||||
}
|
||||
while (bitcount >= 8) {
|
||||
outData.add((byte)0);
|
||||
bitcount -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
// convert back to byte[]
|
||||
byte[] rval = ByteUtil.getByteArrayFromList(outData);
|
||||
|
||||
return rval;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decode by Geoff
|
||||
*
|
||||
* @param raw
|
||||
* @return
|
||||
* @throws NumberFormatException
|
||||
*/
|
||||
public byte[] decode4b6b(byte[] raw) throws RileyLinkCommunicationException {
|
||||
|
||||
StringBuilder errorMessageBuilder = new StringBuilder();
|
||||
|
||||
errorMessageBuilder.append("Input data: " + ByteUtil.getHex(raw) + "\n");
|
||||
|
||||
if ((raw.length % 2) != 0) {
|
||||
errorMessageBuilder.append("Warn: odd number of bytes.\n");
|
||||
}
|
||||
|
||||
byte[] rval = new byte[] {};
|
||||
int availableBits = 0;
|
||||
int codingErrors = 0;
|
||||
int x = 0;
|
||||
// Log.w(TAG,"decode4b6b: untested code");
|
||||
// Log.w(TAG,String.format("Decoding %d bytes: %s",raw.length,ByteUtil.shortHexString(raw)));
|
||||
for (int i = 0; i < raw.length; i++) {
|
||||
int unsignedValue = raw[i];
|
||||
if (unsignedValue < 0) {
|
||||
unsignedValue += 256;
|
||||
}
|
||||
x = (x << 8) + unsignedValue;
|
||||
availableBits += 8;
|
||||
if (availableBits >= 12) {
|
||||
// take top six
|
||||
int highcode = (x >> (availableBits - 6)) & 0x3F;
|
||||
int highIndex = encode4b6bListIndex((byte)(highcode));
|
||||
// take bottom six
|
||||
int lowcode = (x >> (availableBits - 12)) & 0x3F;
|
||||
int lowIndex = encode4b6bListIndex((byte)(lowcode));
|
||||
// special case at end of transmission on uneven boundaries:
|
||||
if ((highIndex >= 0) && (lowIndex >= 0)) {
|
||||
byte decoded = (byte)((highIndex << 4) + lowIndex);
|
||||
rval = ByteUtil.concat(rval, decoded);
|
||||
/*
|
||||
* LOG.debug(String.format(
|
||||
* "i=%d,x=0x%08X,0x%02X->0x%02X, 0x%02X->0x%02X, result: 0x%02X, %d bits remaining, errors %d, bytes remaining: %s"
|
||||
* ,
|
||||
* i,x,highcode,highIndex, lowcode,
|
||||
* lowIndex,decoded,availableBits,codingErrors,ByteUtil.shortHexString
|
||||
* (ByteUtil.substring(raw,i+1,raw.length-i-1))));
|
||||
*/
|
||||
} else {
|
||||
// LOG.debug(String.format("i=%d,x=%08X, coding error: highcode=0x%02X, lowcode=0x%02X, %d bits remaining",i,x,highcode,lowcode,availableBits));
|
||||
errorMessageBuilder.append(String.format(
|
||||
"decode4b6b: i=%d,x=%08X, coding error: highcode=0x%02X, lowcode=0x%02X, %d bits remaining.\n",
|
||||
i, x, highcode, lowcode, availableBits));
|
||||
codingErrors++;
|
||||
}
|
||||
|
||||
availableBits -= 12;
|
||||
x = x & (0x0000ffff >> (16 - availableBits));
|
||||
}
|
||||
}
|
||||
|
||||
if (availableBits != 0) {
|
||||
if ((availableBits == 4) && (x == 0x05)) {
|
||||
// normal end
|
||||
} else {
|
||||
// LOG.error("decode4b6b: failed clean decode -- extra bits available (not marker)(" + availableBits +
|
||||
// ")");
|
||||
errorMessageBuilder.append("decode4b6b: failed clean decode -- extra bits available (not marker)("
|
||||
+ availableBits + ")\n");
|
||||
codingErrors++;
|
||||
}
|
||||
} else {
|
||||
// also normal end.
|
||||
}
|
||||
|
||||
if (codingErrors > 0) {
|
||||
// LOG.error("decode4b6b: " + codingErrors + " coding errors encountered.");
|
||||
errorMessageBuilder.append("decode4b6b: " + codingErrors + " coding errors encountered.");
|
||||
writeError(LOG, raw, errorMessageBuilder.toString());
|
||||
throw new RileyLinkCommunicationException(RileyLinkBLEError.CodingErrors, errorMessageBuilder.toString());
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
// public static RFTools.DecodeResponseDto decode4b6bWithoutException(byte[] raw) {
|
||||
// /*
|
||||
// * if ((raw.length % 2) != 0) {
|
||||
// * LOG.error("Warning: data is odd number of bytes");
|
||||
// * }
|
||||
// */
|
||||
//
|
||||
// RFTools.DecodeResponseDto response = new RFTools.DecodeResponseDto();
|
||||
//
|
||||
// StringBuilder errorMessageBuilder = new StringBuilder();
|
||||
//
|
||||
// errorMessageBuilder.append("Input data: " + ByteUtil.getHex(raw) + "\n");
|
||||
//
|
||||
// if ((raw.length % 2) != 0) {
|
||||
// errorMessageBuilder.append("Warn: odd number of bytes.");
|
||||
// }
|
||||
//
|
||||
// byte[] rval = new byte[] {};
|
||||
// int availableBits = 0;
|
||||
// int codingErrors = 0;
|
||||
// int x = 0;
|
||||
// // Log.w(TAG,"decode4b6b: untested code");
|
||||
// // Log.w(TAG,String.format("Decoding %d bytes: %s",raw.length,ByteUtil.shortHexString(raw)));
|
||||
// for (int i = 0; i < raw.length; i++) {
|
||||
// int unsignedValue = raw[i];
|
||||
// if (unsignedValue < 0) {
|
||||
// unsignedValue += 256;
|
||||
// }
|
||||
// x = (x << 8) + unsignedValue;
|
||||
// availableBits += 8;
|
||||
// if (availableBits >= 12) {
|
||||
// // take top six
|
||||
// int highcode = (x >> (availableBits - 6)) & 0x3F;
|
||||
// int highIndex = encode4b6bListIndex((byte)(highcode));
|
||||
// // take bottom six
|
||||
// int lowcode = (x >> (availableBits - 12)) & 0x3F;
|
||||
// int lowIndex = encode4b6bListIndex((byte)(lowcode));
|
||||
// // special case at end of transmission on uneven boundaries:
|
||||
// if ((highIndex >= 0) && (lowIndex >= 0)) {
|
||||
// byte decoded = (byte)((highIndex << 4) + lowIndex);
|
||||
// rval = ByteUtil.concat(rval, decoded);
|
||||
// /*
|
||||
// * LOG.debug(String.format(
|
||||
// *
|
||||
// "i=%d,x=0x%08X,0x%02X->0x%02X, 0x%02X->0x%02X, result: 0x%02X, %d bits remaining, errors %d, bytes remaining: %s"
|
||||
// * ,
|
||||
// * i,x,highcode,highIndex, lowcode,
|
||||
// * lowIndex,decoded,availableBits,codingErrors,ByteUtil.shortHexString
|
||||
// * (ByteUtil.substring(raw,i+1,raw.length-i-1))));
|
||||
// */
|
||||
// } else {
|
||||
// //
|
||||
// LOG.debug(String.format("i=%d,x=%08X, coding error: highcode=0x%02X, lowcode=0x%02X, %d bits remaining",i,x,highcode,lowcode,availableBits));
|
||||
// errorMessageBuilder.append(String.format(
|
||||
// "decode4b6b: i=%d,x=%08X, coding error: highcode=0x%02X, lowcode=0x%02X, %d bits remaining.\n",
|
||||
// i, x, highcode, lowcode, availableBits));
|
||||
// codingErrors++;
|
||||
// }
|
||||
//
|
||||
// availableBits -= 12;
|
||||
// x = x & (0x0000ffff >> (16 - availableBits));
|
||||
// } else {
|
||||
// // LOG.debug(String.format("i=%d, skip: x=0x%08X, available bits %d",i,x,availableBits));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (availableBits != 0) {
|
||||
// if ((availableBits == 4) && (x == 0x05)) {
|
||||
// // normal end
|
||||
// } else {
|
||||
// LOG.error("decode4b6b: failed clean decode -- extra bits available (not marker)(" + availableBits + ")");
|
||||
// errorMessageBuilder.append("decode4b6b: failed clean decode -- extra bits available (not marker)("
|
||||
// + availableBits + ")\n");
|
||||
// codingErrors++;
|
||||
// }
|
||||
// } else {
|
||||
// // also normal end.
|
||||
// }
|
||||
//
|
||||
// if (codingErrors > 0) {
|
||||
// LOG.error("decode4b6b: " + codingErrors + " coding errors encountered.");
|
||||
// errorMessageBuilder.append("decode4b6b: " + codingErrors + " coding errors encountered.");
|
||||
//
|
||||
// response.errorData = errorMessageBuilder.toString();
|
||||
// } else {
|
||||
// response.data = rval;
|
||||
// }
|
||||
//
|
||||
// return response;
|
||||
// }
|
||||
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.encoding;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkCommunicationException;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkBLEError;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 11/24/18.
|
||||
*/
|
||||
|
||||
public class Encoding4b6bGo extends Encoding4b6bAbstract {
|
||||
|
||||
public static final Logger LOG = LoggerFactory.getLogger(Encoding4b6bGo.class);
|
||||
private static Map<Short, Short> decodeGoMap;
|
||||
|
||||
|
||||
public byte[] encode4b6b(byte[] src) {
|
||||
// 2 input bytes produce 3 output bytes.
|
||||
// Odd final input byte, if any, produces 2 output bytes.
|
||||
int n = src.length;
|
||||
byte[] dst = new byte[3 * (n / 2) + 2 * (n % 2)];
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < n; i += 2, j = j + 3) {
|
||||
short x = convertUnsigned(src[i]);
|
||||
short a = encode4b6bList[hi(4, x)];
|
||||
short b = encode4b6bList[lo(4, x)];
|
||||
dst[j] = (byte)(a << 2 | hi(4, b));
|
||||
if (i + 1 < n) {
|
||||
short y = convertUnsigned(src[i + 1]);
|
||||
short c = encode4b6bList[hi(4, y)];
|
||||
short d = encode4b6bList[lo(4, y)];
|
||||
dst[j + 1] = (byte)(lo(4, b) << 4 | hi(6, c));
|
||||
dst[j + 2] = (byte)(lo(2, c) << 6 | d);
|
||||
} else {
|
||||
// Fill final nibble with 5 to match pump behavior.
|
||||
dst[j + 1] = (byte)(lo(4, b) << 4 | 0x5);
|
||||
}
|
||||
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decode from Go code by ecc1. NOT WORKING
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public byte[] decode4b6b(byte[] src) throws RileyLinkCommunicationException {
|
||||
int n = src.length;
|
||||
|
||||
if (decodeGoMap == null)
|
||||
initDecodeGo();
|
||||
|
||||
StringBuilder errorMessageBuilder = new StringBuilder();
|
||||
|
||||
errorMessageBuilder.append("Input data: " + ByteUtil.getHex(src) + "\n");
|
||||
int codingErrors = 0;
|
||||
|
||||
// Check for valid packet length.
|
||||
if (n % 3 == 1) {
|
||||
errorMessageBuilder.append("Invalid package length " + n);
|
||||
codingErrors++;
|
||||
// return nil, ErrDecoding
|
||||
}
|
||||
// 3 input bytes produce 2 output bytes.
|
||||
// Final 2 input bytes, if any, produce 1 output byte.
|
||||
byte[] dst = new byte[2 * (n / 3) + (n % 3) / 2];
|
||||
|
||||
int j = 0;
|
||||
for (int i = 0; i < n; i = i + 3, j = j + 2) {
|
||||
if (i + 1 >= n) {
|
||||
errorMessageBuilder.append("Overflow in i (" + i + ")");
|
||||
}
|
||||
short x = convertUnsigned(src[i]);
|
||||
short y = convertUnsigned(src[i + 1]);
|
||||
short a = decode6b_goMap(hi(6, x));
|
||||
short b = decode6b_goMap(lo(2, x) << 4 | hi(4, y));
|
||||
if (a == 0xFF || b == 0xFF) {
|
||||
errorMessageBuilder.append("Error decoding ");
|
||||
codingErrors++;
|
||||
}
|
||||
dst[j] = (byte)(a << 4 | b);
|
||||
if (i + 2 < n) {
|
||||
short z = convertUnsigned(src[i + 2]);
|
||||
short c = decode6b_goMap(lo(4, y) << 2 | hi(2, z));
|
||||
short d = decode6b_goMap(lo(6, z));
|
||||
if (c == 0xFF || d == 0xFF) {
|
||||
errorMessageBuilder.append("Error decoding ");
|
||||
codingErrors++;
|
||||
}
|
||||
dst[j + 1] = (byte)(c << 4 | d);
|
||||
}
|
||||
}
|
||||
|
||||
if (codingErrors > 0) {
|
||||
errorMessageBuilder.append("decode4b6b: " + codingErrors + " coding errors encountered.");
|
||||
writeError(LOG, dst, errorMessageBuilder.toString());
|
||||
throw new RileyLinkCommunicationException(RileyLinkBLEError.CodingErrors, errorMessageBuilder.toString());
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
static short hi(int n, short x) {
|
||||
// x = convertUnsigned(x);
|
||||
return (short)(x >> (8 - n));
|
||||
}
|
||||
|
||||
|
||||
static short lo(int n, short x) {
|
||||
// byte b = (byte)x;
|
||||
return (short)(x & ((1 << n) - 1));
|
||||
}
|
||||
|
||||
|
||||
public static void initDecodeGo() {
|
||||
|
||||
decodeGoMap = new HashMap<>();
|
||||
|
||||
putToMap(0x0B, 0x0B);
|
||||
putToMap(0x0D, 0x0D);
|
||||
putToMap(0x0E, 0x0E);
|
||||
putToMap(0x15, 0x00);
|
||||
putToMap(0x16, 0x07);
|
||||
putToMap(0x19, 0x09);
|
||||
putToMap(0x1A, 0x08);
|
||||
putToMap(0x1C, 0x0F);
|
||||
putToMap(0x23, 0x03);
|
||||
putToMap(0x25, 0x05);
|
||||
putToMap(0x26, 0x06);
|
||||
putToMap(0x2A, 0x0A);
|
||||
putToMap(0x2C, 0x0C);
|
||||
putToMap(0x31, 0x01);
|
||||
putToMap(0x32, 0x02);
|
||||
putToMap(0x34, 0x04);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static short decode6b_goMap(int value) {
|
||||
short val = (short)value;
|
||||
if (decodeGoMap.containsKey(val))
|
||||
return decodeGoMap.get(val);
|
||||
else
|
||||
return (short)0xff;
|
||||
}
|
||||
|
||||
|
||||
private static void putToMap(int val1, int val2) {
|
||||
decodeGoMap.put((short)val1, (short)val2);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.encoding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkCommunicationException;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 11/24/18.
|
||||
*/
|
||||
|
||||
public class Encoding4b6bLoop extends Encoding4b6bAbstract {
|
||||
|
||||
public static final Logger LOG = LoggerFactory.getLogger(Encoding4b6bLoop.class);
|
||||
public Map<Integer, Byte> codesRev = null;
|
||||
|
||||
|
||||
public Encoding4b6bLoop() {
|
||||
createCodeRev();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is almost 1:1 with same method from Loop, only change is unsigning of element and |05 added for
|
||||
* last byte. It should work better than original one, which is really different than this one.
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public byte[] encode4b6b(byte[] data) {
|
||||
|
||||
List<Byte> buffer = new ArrayList<Byte>();
|
||||
int bitAccumulator = 0x0;
|
||||
int bitcount = 0;
|
||||
|
||||
for (byte element : data) {
|
||||
|
||||
short element2 = element;
|
||||
|
||||
if (element2 < 0) {
|
||||
element2 += 256;
|
||||
}
|
||||
|
||||
bitAccumulator <<= 6;
|
||||
bitAccumulator |= encode4b6bList[element2 >> 4];
|
||||
bitcount += 6;
|
||||
|
||||
bitAccumulator <<= 6;
|
||||
bitAccumulator |= encode4b6bList[element2 & 0x0f];
|
||||
bitcount += 6;
|
||||
|
||||
while (bitcount >= 8) {
|
||||
buffer.add((byte)((bitAccumulator >> (bitcount - 8)) & 0xff));
|
||||
bitcount -= 8;
|
||||
bitAccumulator &= (0xffff >> (16 - bitcount));
|
||||
}
|
||||
}
|
||||
|
||||
if (bitcount > 0) {
|
||||
bitAccumulator <<= (8 - bitcount);
|
||||
buffer.add((byte)((bitAccumulator | 0x5) & 0xff));
|
||||
}
|
||||
|
||||
return ByteUtil.getByteArrayFromList(buffer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DOESN'T WORK YET
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
* @throws RileyLinkCommunicationException
|
||||
*/
|
||||
public byte[] decode4b6b(byte[] data) throws RileyLinkCommunicationException {
|
||||
List<Byte> buffer = new ArrayList<Byte>();
|
||||
int availBits = 0;
|
||||
int bitAccumulator = 0;
|
||||
|
||||
for (byte element2 : data) {
|
||||
|
||||
short element = convertUnsigned(element2);
|
||||
|
||||
// if (element < 0) {
|
||||
// element += 255;
|
||||
// }
|
||||
|
||||
if (element == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
bitAccumulator = (bitAccumulator << 8) + element;
|
||||
availBits += 8;
|
||||
|
||||
if (availBits >= 12) {
|
||||
|
||||
int hiNibble;
|
||||
int loNibble;
|
||||
|
||||
try {
|
||||
int index = (bitAccumulator >> (availBits - 6));
|
||||
int index2 = ((bitAccumulator >> (availBits - 12)) & 0b111111);
|
||||
hiNibble = codesRev.get((bitAccumulator >> (availBits - 6)));
|
||||
loNibble = codesRev.get(((bitAccumulator >> (availBits - 12)) & 0b111111));
|
||||
} catch (Exception ex) {
|
||||
System.out.println("Exception: " + ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
int decoded = ((hiNibble << 4) + loNibble);
|
||||
buffer.add((byte)decoded);
|
||||
availBits -= 12;
|
||||
bitAccumulator = bitAccumulator & (0xffff >> (16 - availBits));
|
||||
}
|
||||
}
|
||||
|
||||
return ByteUtil.getByteArrayFromList(buffer);
|
||||
}
|
||||
|
||||
|
||||
private void createCodeRev() {
|
||||
codesRev = new HashMap<>();
|
||||
|
||||
for (int i = 0; i < encode4b6bList.length; i++) {
|
||||
codesRev.put(i, encode4b6bList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs;
|
||||
|
||||
/**
|
||||
* Created by andy on 11/24/18.
|
||||
*/
|
||||
|
||||
public enum RileyLinkBLEError {
|
||||
CodingErrors("Coding Errors encpountered during decode of RileyLink packet."), //
|
||||
Timeout("Timeout"), //
|
||||
Interrupted("Interrupted");
|
||||
|
||||
private String description;
|
||||
|
||||
|
||||
RileyLinkBLEError(String description) {
|
||||
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
|
@ -81,7 +81,7 @@ public enum RileyLinkServiceState {
|
|||
this == RileyLinkServiceState.BluetoothReady || //
|
||||
this == RileyLinkServiceState.RileyLinkInitializing || //
|
||||
this == RileyLinkReady
|
||||
// this == RileyLinkServiceState.RileyLinkError
|
||||
// this == RileyLinkServiceState.RileyLinkBLEError
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ public class RileyLinkBroadcastReceiver extends BroadcastReceiver {
|
|||
if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnected)) {
|
||||
if (BluetoothAdapter.getDefaultAdapter().isEnabled()) {
|
||||
RileyLinkUtil
|
||||
.setServiceState(RileyLinkServiceState.BluetoothReady, RileyLinkError.RileyLinkUnreachable);
|
||||
.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.RileyLinkUnreachable);
|
||||
} else {
|
||||
RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled);
|
||||
}
|
||||
|
@ -173,15 +173,6 @@ public class RileyLinkBroadcastReceiver extends BroadcastReceiver {
|
|||
ServiceTaskExecutor.startTask(task);
|
||||
LOG.info("Announcing RileyLink open For business");
|
||||
|
||||
return true;
|
||||
} else if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnected)) {
|
||||
if (BluetoothAdapter.getDefaultAdapter().isEnabled()) {
|
||||
RileyLinkUtil
|
||||
.setServiceState(RileyLinkServiceState.BluetoothReady, RileyLinkError.RileyLinkUnreachable);
|
||||
} else {
|
||||
RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (action.equals(RileyLinkConst.Intents.RileyLinkNewAddressSet)) {
|
||||
String RileylinkBLEAddress = SP.getString(RileyLinkConst.Prefs.RileyLinkAddress, "");
|
||||
|
|
|
@ -8,6 +8,7 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLink
|
|||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkServiceState;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkTargetDevice;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.data.ServiceTransport;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicConst;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +41,11 @@ public class InitializePumpManagerTask extends ServiceTask {
|
|||
|
||||
RileyLinkUtil.getRileyLinkServiceData().lastGoodFrequency = lastGoodFrequency;
|
||||
|
||||
if (RileyLinkUtil.getRileyLinkTargetFrequency() == null) {
|
||||
String pumpFrequency = SP.getString(MedtronicConst.Prefs.PumpFrequency, null);
|
||||
|
||||
}
|
||||
|
||||
if ((lastGoodFrequency > 0.0d)
|
||||
&& RileyLinkUtil.getRileyLinkCommunicationManager().isValidFrequency(lastGoodFrequency)) {
|
||||
|
||||
|
|
|
@ -137,21 +137,41 @@ public class ByteUtil {
|
|||
}
|
||||
|
||||
|
||||
public static byte[] fromByteArray(List<Byte> byteArray) {
|
||||
byte[] rval = new byte[byteArray.size()];
|
||||
for (int i = 0; i < byteArray.size(); i++) {
|
||||
rval[i] = byteArray.get(i);
|
||||
// public static byte[] fromByteList(List<Byte> byteArray) {
|
||||
// byte[] rval = new byte[byteArray.size()];
|
||||
// for (int i = 0; i < byteArray.size(); i++) {
|
||||
// rval[i] = byteArray.get(i);
|
||||
// }
|
||||
// return rval;
|
||||
// }
|
||||
|
||||
// public static List<Byte> toByteList(byte[] data) {
|
||||
// ArrayList<Byte> rval = new ArrayList<>(data.length);
|
||||
// for (int i = 0; i < data.length; i++) {
|
||||
// rval.add(i, new Byte(data[i]));
|
||||
// }
|
||||
// return rval;
|
||||
// }
|
||||
|
||||
public static List<Byte> getListFromByteArray(byte[] array) {
|
||||
List<Byte> listOut = new ArrayList<Byte>();
|
||||
|
||||
for (byte val : array) {
|
||||
listOut.add(val);
|
||||
}
|
||||
return rval;
|
||||
|
||||
return listOut;
|
||||
}
|
||||
|
||||
|
||||
public static ArrayList<Byte> toByteArray(byte[] data) {
|
||||
ArrayList<Byte> rval = new ArrayList<>(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
rval.add(i, new Byte(data[i]));
|
||||
public static byte[] getByteArrayFromList(List<Byte> list) {
|
||||
byte[] out = new byte[list.size()];
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
out[i] = list.get(i);
|
||||
}
|
||||
return rval;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
@ -233,17 +253,6 @@ public class ByteUtil {
|
|||
}
|
||||
|
||||
|
||||
public static List<Byte> getListFromByteArray(byte[] array) {
|
||||
List<Byte> listOut = new ArrayList<Byte>();
|
||||
|
||||
for (byte val : array) {
|
||||
listOut.add(val);
|
||||
}
|
||||
|
||||
return listOut;
|
||||
}
|
||||
|
||||
|
||||
public static int makeUnsignedShort(int i, int j) {
|
||||
int k = (i & 0xff) << 8 | j & 0xff;
|
||||
return k;
|
||||
|
@ -275,19 +284,20 @@ public class ByteUtil {
|
|||
}
|
||||
|
||||
|
||||
public static byte[] getByteArrayFromList(List<Byte> list) {
|
||||
byte[] out = new byte[list.size()];
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
out[i] = list.get(i);
|
||||
}
|
||||
|
||||
return out;
|
||||
public static String getHex(byte abyte0[]) {
|
||||
return abyte0 != null ? getHex(abyte0, abyte0.length) : null;
|
||||
}
|
||||
|
||||
|
||||
public static String getHex(byte abyte0[]) {
|
||||
return abyte0 != null ? getHex(abyte0, abyte0.length) : null;
|
||||
public static String getString(short abyte0[]) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (short i : abyte0) {
|
||||
sb.append(i);
|
||||
sb.append(" ");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
@ -370,12 +380,17 @@ public class ByteUtil {
|
|||
}
|
||||
|
||||
|
||||
public static byte[] createByteArray(String dataFull, int startIndex) {
|
||||
return createByteArray(dataFull, startIndex, dataFull.length());
|
||||
public static byte[] createByteArrayFromCompactString(String dataFull) {
|
||||
return createByteArrayFromCompactString(dataFull, 0, dataFull.length());
|
||||
}
|
||||
|
||||
|
||||
public static byte[] createByteArray(String dataFull, int startIndex, int length) {
|
||||
public static byte[] createByteArrayFromCompactString(String dataFull, int startIndex) {
|
||||
return createByteArrayFromCompactString(dataFull, startIndex, dataFull.length());
|
||||
}
|
||||
|
||||
|
||||
public static byte[] createByteArrayFromCompactString(String dataFull, int startIndex, int length) {
|
||||
|
||||
String data = dataFull.substring(startIndex);
|
||||
|
||||
|
|
|
@ -231,7 +231,15 @@ public class MedtronicFragment extends SubscriberFragment {
|
|||
} else if (pumpStatus.rileyLinkServiceState.isConnecting()) {
|
||||
rileyLinkStatus.setText("{fa-bluetooth-b spin} " + getTranslation(resourceId));
|
||||
} else if (pumpStatus.rileyLinkServiceState.isError()) {
|
||||
rileyLinkStatus.setText("{fa-bluetooth-b} " + getTranslation(resourceId));
|
||||
|
||||
RileyLinkError rileyLinkError = RileyLinkUtil.getError();
|
||||
|
||||
if (rileyLinkError == null)
|
||||
rileyLinkStatus.setText("{fa-bluetooth-b} " + getTranslation(resourceId));
|
||||
else
|
||||
rileyLinkStatus.setText("{fa-bluetooth-b} "
|
||||
+ getTranslation(rileyLinkError.getResourceId(RileyLinkTargetDevice.MedtronicPump)));
|
||||
|
||||
rileyLinkStatus.setTextColor(Color.RED);
|
||||
} else {
|
||||
rileyLinkStatus.setText("{fa-bluetooth-b} " + getTranslation(resourceId));
|
||||
|
@ -274,8 +282,27 @@ public class MedtronicFragment extends SubscriberFragment {
|
|||
|
||||
if (cmd == null)
|
||||
pumpStatusIconView.setText(" " + MainApp.gs(pumpStatus.pumpDeviceState.getResourceId()));
|
||||
else
|
||||
pumpStatusIconView.setText(" " + cmd.name());
|
||||
else {
|
||||
Integer resourceId = cmd.getResourceId();
|
||||
|
||||
if (cmd == MedtronicCommandType.GetHistoryData) {
|
||||
|
||||
if (resourceId == null) {
|
||||
pumpStatusIconView.setText(String.format(" Get History - Page %d (%d/16)",
|
||||
MedtronicUtil.pageNumber, MedtronicUtil.frameNumber));
|
||||
} else {
|
||||
pumpStatusIconView.setText(MainApp.gs(resourceId, MedtronicUtil.pageNumber,
|
||||
MedtronicUtil.frameNumber));
|
||||
}
|
||||
} else {
|
||||
if (resourceId == null) {
|
||||
pumpStatusIconView.setText(" " + cmd.name());
|
||||
} else {
|
||||
pumpStatusIconView.setText(" " + getTranslation(resourceId));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -118,13 +118,15 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
serviceConnection = new ServiceConnection() {
|
||||
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
LOG.debug("RileyLinkMedtronicService is disconnected");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("RileyLinkMedtronicService is disconnected");
|
||||
medtronicService = null;
|
||||
}
|
||||
|
||||
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
LOG.debug("RileyLinkMedtronicService is connected");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("RileyLinkMedtronicService is connected");
|
||||
RileyLinkMedtronicService.LocalBinder mLocalBinder = (RileyLinkMedtronicService.LocalBinder)service;
|
||||
medtronicService = mLocalBinder.getServiceInstance();
|
||||
|
||||
|
@ -134,7 +136,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
SystemClock.sleep(5000);
|
||||
|
||||
if (MedtronicUtil.getPumpStatus() != null) {
|
||||
LOG.debug("Starting Medtronic-RileyLink service");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("Starting Medtronic-RileyLink service");
|
||||
if (MedtronicUtil.getPumpStatus().setNotInPreInit()) {
|
||||
break;
|
||||
}
|
||||
|
@ -170,7 +173,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
pumpStatusLocal.refreshConfiguration();
|
||||
|
||||
LOG.debug("initPumpStatusData: {}", this.pumpStatusLocal);
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("initPumpStatusData: {}", this.pumpStatusLocal);
|
||||
|
||||
this.pumpStatus = pumpStatusLocal;
|
||||
|
||||
|
@ -182,6 +186,17 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
SP.putLong(MedtronicConst.Statistics.FirstPumpStart, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
migrateSettings();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void migrateSettings() {
|
||||
|
||||
if ("US (916 MHz)".equals(SP.getString(MedtronicConst.Prefs.PumpFrequency, null))) {
|
||||
SP.putString(MedtronicConst.Prefs.PumpFrequency, MainApp.gs(R.string.medtronic_pump_frequency_us_ca));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -193,7 +208,10 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
do {
|
||||
SystemClock.sleep(60000);
|
||||
|
||||
if (doWeHaveAnyStatusNeededRefereshing()) {
|
||||
Map<MedtronicStatusRefreshType, Long> statusRefresh = workWithStatusRefresh(
|
||||
StatusRefreshAction.GetData, null, null);
|
||||
|
||||
if (doWeHaveAnyStatusNeededRefereshing(statusRefresh)) {
|
||||
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Scheduled Status Refresh", null);
|
||||
}
|
||||
|
||||
|
@ -230,7 +248,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
@Override
|
||||
public boolean isInitialized() {
|
||||
// TODO remove
|
||||
LOG.debug("MedtronicPumpPlugin::isInitialized");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("MedtronicPumpPlugin::isInitialized");
|
||||
return isServiceSet() && isInitialized;
|
||||
}
|
||||
|
||||
|
@ -245,7 +264,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
@Override
|
||||
public boolean isBusy() {
|
||||
// TODO remove
|
||||
LOG.debug("MedtronicPumpPlugin::isBusy");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("MedtronicPumpPlugin::isBusy");
|
||||
return isServiceSet() && medtronicService.isBusy();
|
||||
}
|
||||
|
||||
|
@ -253,7 +273,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
@Override
|
||||
public boolean isConnected() {
|
||||
// TODO remove
|
||||
LOG.debug("MedtronicPumpPlugin::isConnected");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("MedtronicPumpPlugin::isConnected");
|
||||
return isServiceSet() && medtronicService.isInitialized();
|
||||
}
|
||||
|
||||
|
@ -261,7 +282,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
@Override
|
||||
public boolean isConnecting() {
|
||||
// TODO remove
|
||||
LOG.debug("MedtronicPumpPlugin::isConnecting");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("MedtronicPumpPlugin::isConnecting");
|
||||
return !isServiceSet() || !medtronicService.isInitialized();
|
||||
}
|
||||
|
||||
|
@ -294,7 +316,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
if (rileyLinkServiceState != RileyLinkServiceState.PumpConnectorReady //
|
||||
&& rileyLinkServiceState != RileyLinkServiceState.RileyLinkReady //
|
||||
&& rileyLinkServiceState != RileyLinkServiceState.TuneUpDevice) {
|
||||
LOG.error("RileyLink unreachable.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.error("RileyLink unreachable.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -304,14 +327,18 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
private void refreshAnyStatusThatNeedsToBeRefreshed() {
|
||||
|
||||
if (!doWeHaveAnyStatusNeededRefereshing()) {
|
||||
Map<MedtronicStatusRefreshType, Long> statusRefresh = workWithStatusRefresh(StatusRefreshAction.GetData, null,
|
||||
null);
|
||||
|
||||
if (!doWeHaveAnyStatusNeededRefereshing(statusRefresh)) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean resetTime = false;
|
||||
|
||||
if (isPumpNotReachable()) {
|
||||
LOG.error("Pump unreachable.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.error("Pump unreachable.");
|
||||
MedtronicUtil.sendNotification(MedtronicNotificationType.PumpUnreachable);
|
||||
|
||||
return;
|
||||
|
@ -322,7 +349,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
Set<MedtronicStatusRefreshType> refreshTypesNeededToReschedule = new HashSet<>();
|
||||
|
||||
// execute
|
||||
for (Map.Entry<MedtronicStatusRefreshType, Long> refreshType : statusRefreshMap.entrySet()) {
|
||||
for (Map.Entry<MedtronicStatusRefreshType, Long> refreshType : statusRefresh.entrySet()) {
|
||||
|
||||
if (refreshType.getValue() > 0 && System.currentTimeMillis() > refreshType.getValue()) {
|
||||
|
||||
|
@ -361,9 +388,9 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
}
|
||||
|
||||
|
||||
private boolean doWeHaveAnyStatusNeededRefereshing() {
|
||||
private boolean doWeHaveAnyStatusNeededRefereshing(Map<MedtronicStatusRefreshType, Long> statusRefresh) {
|
||||
|
||||
for (Map.Entry<MedtronicStatusRefreshType, Long> refreshType : statusRefreshMap.entrySet()) {
|
||||
for (Map.Entry<MedtronicStatusRefreshType, Long> refreshType : statusRefresh.entrySet()) {
|
||||
|
||||
if (refreshType.getValue() > 0 && System.currentTimeMillis() > refreshType.getValue()) {
|
||||
return true;
|
||||
|
@ -381,7 +408,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
private void initializePump(boolean realInit) {
|
||||
|
||||
LOG.info(getLogPrefix() + "initializePump - start");
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "initializePump - start");
|
||||
|
||||
if (medtronicCommunicationManager == null) {
|
||||
medtronicCommunicationManager = MedtronicCommunicationManager.getInstance();
|
||||
|
@ -394,7 +422,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
if (isRefresh) {
|
||||
if (isPumpNotReachable()) {
|
||||
LOG.error(getLogPrefix() + "initializePump::Pump unreachable.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.error(getLogPrefix() + "initializePump::Pump unreachable.");
|
||||
MedtronicUtil.sendNotification(MedtronicNotificationType.PumpUnreachable);
|
||||
|
||||
setRefreshButtonEnabled(true);
|
||||
|
@ -410,7 +439,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
medtronicUIComm.executeCommand(MedtronicCommandType.PumpModel);
|
||||
} else {
|
||||
if (pumpStatusLocal.medtronicDeviceType != MedtronicUtil.getMedtronicPumpModel()) {
|
||||
LOG.warn(getLogPrefix() + "Configured pump is not the same as one detected.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn(getLogPrefix() + "Configured pump is not the same as one detected.");
|
||||
MedtronicUtil.sendNotification(MedtronicNotificationType.PumpTypeNotSame);
|
||||
}
|
||||
}
|
||||
|
@ -443,7 +473,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
int errorCount = medtronicUIComm.getInvalidResponsesCount();
|
||||
|
||||
if (errorCount >= 5) {
|
||||
LOG.error("Number of error counts was 5 or more. Starting tunning.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.error("Number of error counts was 5 or more. Starting tunning.");
|
||||
setRefreshButtonEnabled(true);
|
||||
ServiceTaskExecutor.startTask(new WakeAndTuneTask());
|
||||
return;
|
||||
|
@ -523,15 +554,18 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
}
|
||||
|
||||
if (!invalid) {
|
||||
LOG.debug("Basal profile is same as AAPS one.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("Basal profile is same as AAPS one.");
|
||||
basalProfileChanged = false;
|
||||
} else {
|
||||
LOG.debug("Basal profile on Pump is different than the AAPS one.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("Basal profile on Pump is different than the AAPS one.");
|
||||
}
|
||||
|
||||
} else {
|
||||
invalid = true;
|
||||
LOG.debug("Basal profile NO DATA");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("Basal profile NO DATA");
|
||||
}
|
||||
|
||||
isBasalProfileInvalid = invalid;
|
||||
|
@ -563,7 +597,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
private MedtronicPumpStatus getMDTPumpStatus() {
|
||||
if (pumpStatusLocal == null) {
|
||||
// FIXME I don't know why this happens
|
||||
LOG.warn("!!!! Reset Pump Status Local");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("!!!! Reset Pump Status Local");
|
||||
pumpStatusLocal = MedtronicUtil.getPumpStatus();
|
||||
}
|
||||
|
||||
|
@ -602,6 +637,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
// TODO display bolus
|
||||
|
||||
setRefreshButtonEnabled(true);
|
||||
|
||||
if (response) {
|
||||
// FIXME this needs to be fixed to read info from history
|
||||
boolean treatmentCreated = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true);
|
||||
|
@ -613,14 +650,17 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
incrementStatistics(detailedBolusInfo.isSMB ? MedtronicConst.Statistics.SMBBoluses
|
||||
: MedtronicConst.Statistics.StandardBoluses);
|
||||
|
||||
return new PumpEnactResult().success(response) //
|
||||
.enacted(response) //
|
||||
.bolusDelivered(detailedBolusInfo.insulin) //
|
||||
.carbsDelivered(detailedBolusInfo.carbs);
|
||||
} else {
|
||||
|
||||
return new PumpEnactResult().success(false).enacted(false) //
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_bolus_could_not_be_delivered));
|
||||
}
|
||||
|
||||
// readPumpHistory();
|
||||
|
||||
setRefreshButtonEnabled(true);
|
||||
|
||||
return new PumpEnactResult().success(response).enacted(response);
|
||||
|
||||
// pump.activity = MainApp.gs(R.string.combo_pump_action_bolusing, detailedBolusInfo.insulin);
|
||||
// MainApp.bus().post(new EventComboPumpUpdateGUI());
|
||||
//
|
||||
|
@ -769,19 +809,22 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
getMDTPumpStatus();
|
||||
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute: rate: {}, duration={}", absoluteRate, durationInMinutes);
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute: rate: {}, duration={}", absoluteRate, durationInMinutes);
|
||||
|
||||
// read current TBR
|
||||
TempBasalPair tbrCurrent = readTBR();
|
||||
|
||||
if (tbrCurrent == null) {
|
||||
LOG.warn(getLogPrefix() + "setTempBasalAbsolute - Could not read current TBR, canceling operation.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn(getLogPrefix() + "setTempBasalAbsolute - Could not read current TBR, canceling operation.");
|
||||
finishAction("TBR");
|
||||
return new PumpEnactResult().success(false).enacted(false)
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_cant_read_tbr));
|
||||
} else {
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute: Current Basal: duration: {} min, rate={}",
|
||||
tbrCurrent.getDurationMinutes(), tbrCurrent.getInsulinRate());
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute: Current Basal: duration: {} min, rate={}",
|
||||
tbrCurrent.getDurationMinutes(), tbrCurrent.getInsulinRate());
|
||||
}
|
||||
|
||||
if (!enforceNew) {
|
||||
|
@ -795,7 +838,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
}
|
||||
|
||||
if (sameRate) {
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - No enforceNew and same rate. Exiting.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - No enforceNew and same rate. Exiting.");
|
||||
finishAction("TBR");
|
||||
return new PumpEnactResult().success(true).enacted(false);
|
||||
}
|
||||
|
@ -805,7 +849,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
// if TBR is running we will cancel it.
|
||||
if (tbrCurrent.getInsulinRate() != 0.0f && tbrCurrent.getDurationMinutes() > 0) {
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - TBR running - so canceling it.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - TBR running - so canceling it.");
|
||||
|
||||
// CANCEL
|
||||
|
||||
|
@ -814,14 +859,16 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
Boolean response = (Boolean)responseTask2.returnData;
|
||||
|
||||
if (response) {
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - Current TBR cancelled.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - Current TBR cancelled.");
|
||||
} else {
|
||||
LOG.error(getLogPrefix() + "setTempBasalAbsolute - Cancel TBR failed.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.error(getLogPrefix() + "setTempBasalAbsolute - Cancel TBR failed.");
|
||||
|
||||
finishAction("TBR");
|
||||
|
||||
return new PumpEnactResult().success(false).enacted(false)
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_cant_cancel_tbr));
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_cant_cancel_tbr_stop_op));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -831,7 +878,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
Boolean response = (Boolean)responseTask.returnData;
|
||||
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - setTBR. Response: " + response);
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - setTBR. Response: " + response);
|
||||
|
||||
if (response) {
|
||||
// FIXME put this into UIPostProcessor
|
||||
|
@ -848,13 +896,19 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempStart);
|
||||
|
||||
incrementStatistics(MedtronicConst.Statistics.TBRsSet);
|
||||
|
||||
finishAction("TBR");
|
||||
|
||||
return new PumpEnactResult().success(response).enacted(response) //
|
||||
.absolute(absoluteRate).duration(durationInMinutes);
|
||||
|
||||
} else {
|
||||
finishAction("TBR");
|
||||
|
||||
return new PumpEnactResult().success(response).enacted(response) //
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_tbr_could_not_be_delivered));
|
||||
}
|
||||
|
||||
finishAction("TBR");
|
||||
|
||||
setRefreshButtonEnabled(true);
|
||||
|
||||
return new PumpEnactResult().success(response).enacted(response);
|
||||
}
|
||||
|
||||
|
||||
|
@ -871,7 +925,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
private void readPumpHistory() {
|
||||
|
||||
LOG.error(getLogPrefix() + "readPumpHistory WIP.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.error(getLogPrefix() + "readPumpHistory WIP.");
|
||||
|
||||
readPumpHistoryLogic();
|
||||
|
||||
|
@ -894,12 +949,14 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
if (medtronicHistoryData.isPumpSuspended(this.pumpState == PumpDriverState.Suspended)) {
|
||||
scheduleNextRefresh(MedtronicStatusRefreshType.PumpTime, -1);
|
||||
this.pumpState = PumpDriverState.Suspended;
|
||||
LOG.debug(getLogPrefix() + "isPumpSuspended: true");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug(getLogPrefix() + "isPumpSuspended: true");
|
||||
} else {
|
||||
if (previousState == PumpDriverState.Suspended) {
|
||||
this.pumpState = PumpDriverState.Ready;
|
||||
}
|
||||
LOG.debug(getLogPrefix() + "isPumpSuspended: false");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug(getLogPrefix() + "isPumpSuspended: false");
|
||||
}
|
||||
|
||||
List<PumpHistoryEntry> tdds = medtronicHistoryData.getTDDs();
|
||||
|
@ -910,6 +967,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
List<PumpHistoryEntry> tdds2 = medtronicHistoryData.getTDDs2();
|
||||
|
||||
// FIXME
|
||||
LOG.debug("TDDs2: {}", gsonInstancePretty.toJson(tdds2));
|
||||
|
||||
List<PumpHistoryEntry> treatments = medtronicHistoryData.getTreatments();
|
||||
|
@ -954,7 +1012,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
if (lastPumpHistoryEntry == null) {
|
||||
|
||||
LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntry: null");
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntry: null");
|
||||
|
||||
Long lastPumpHistoryEntryTime = SP.getLong(MedtronicConst.Statistics.LastPumpHistoryEntry, 0L);
|
||||
|
||||
|
@ -963,14 +1022,16 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
medtronicHistoryData.setIsInInit(true);
|
||||
|
||||
if (lastPumpHistoryEntryTime == 0L) {
|
||||
LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntryTime: 0L - targetDate: "
|
||||
+ targetDate);
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntryTime: 0L - targetDate: "
|
||||
+ targetDate);
|
||||
targetDate = timeMinus36h;
|
||||
} else {
|
||||
LocalDateTime lastHistoryRecordTime = DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime);
|
||||
|
||||
LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntryTime: {} - targetDate: {}",
|
||||
lastHistoryRecordTime, targetDate);
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntryTime: {} - targetDate: {}",
|
||||
lastHistoryRecordTime, targetDate);
|
||||
|
||||
medtronicHistoryData.setLastHistoryRecordTime(DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime));
|
||||
|
||||
|
@ -984,11 +1045,13 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
targetDate = (timeMinus36h.isAfter(lastHistoryRecordTime) ? timeMinus36h : lastHistoryRecordTime);
|
||||
|
||||
LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): targetDate: " + targetDate);
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): targetDate: " + targetDate);
|
||||
}
|
||||
} else {
|
||||
LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntry: not null - {}",
|
||||
gsonInstancePretty.toJson(lastPumpHistoryEntry));
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntry: not null - {}",
|
||||
gsonInstancePretty.toJson(lastPumpHistoryEntry));
|
||||
medtronicHistoryData.setIsInInit(false);
|
||||
medtronicHistoryData.setLastHistoryRecordTime(null);
|
||||
}
|
||||
|
@ -1000,7 +1063,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
PumpHistoryEntry latestEntry = historyResult.getLatestEntry();
|
||||
|
||||
LOG.debug(getLogPrefix() + "Last entry: " + latestEntry);
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug(getLogPrefix() + "Last entry: " + latestEntry);
|
||||
|
||||
if (latestEntry == null) // no new history to read
|
||||
return;
|
||||
|
@ -1053,20 +1117,50 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
else
|
||||
min = 15;
|
||||
|
||||
statusRefreshMap.put(refreshType, getTimeInFutureFromMinutes(min));
|
||||
workWithStatusRefresh(StatusRefreshAction.Add, refreshType, getTimeInFutureFromMinutes(min));
|
||||
}
|
||||
break;
|
||||
|
||||
case PumpTime:
|
||||
case Configuration:
|
||||
case PumpHistory: {
|
||||
statusRefreshMap.put(refreshType, getTimeInFutureFromMinutes(refreshType.getRefreshTime()
|
||||
+ additionalTimeInMinutes));
|
||||
workWithStatusRefresh(StatusRefreshAction.Add, refreshType,
|
||||
getTimeInFutureFromMinutes(refreshType.getRefreshTime() + additionalTimeInMinutes));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private enum StatusRefreshAction {
|
||||
Add, //
|
||||
GetData;
|
||||
}
|
||||
|
||||
|
||||
private synchronized Map<MedtronicStatusRefreshType, Long> workWithStatusRefresh(StatusRefreshAction action,
|
||||
MedtronicStatusRefreshType statusRefreshType, Long time) {
|
||||
|
||||
switch (action) {
|
||||
|
||||
case Add: {
|
||||
statusRefreshMap.put(statusRefreshType, time);
|
||||
return null;
|
||||
}
|
||||
|
||||
case GetData: {
|
||||
Map<MedtronicStatusRefreshType, Long> shallowCopy = new HashMap<>();
|
||||
|
||||
shallowCopy.putAll(statusRefreshMap);
|
||||
return shallowCopy;
|
||||
}
|
||||
|
||||
default:
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private long getTimeInFutureFromMinutes(int minutes) {
|
||||
return System.currentTimeMillis() + getTimeInMs(minutes);
|
||||
|
@ -1099,7 +1193,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
@Override
|
||||
public PumpEnactResult cancelTempBasal(boolean enforceNew) {
|
||||
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - started");
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - started");
|
||||
|
||||
if (isPumpNotReachable()) {
|
||||
|
||||
|
@ -1118,12 +1213,14 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
if (tbrCurrent != null) {
|
||||
if (tbrCurrent.getInsulinRate() == 0.0f && tbrCurrent.getDurationMinutes() == 0) {
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - TBR already canceled.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - TBR already canceled.");
|
||||
finishAction("TBR");
|
||||
return new PumpEnactResult().success(true).enacted(false);
|
||||
}
|
||||
} else {
|
||||
LOG.warn(getLogPrefix() + "cancelTempBasal - Could not read currect TBR, canceling operation.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn(getLogPrefix() + "cancelTempBasal - Could not read currect TBR, canceling operation.");
|
||||
finishAction("TBR");
|
||||
return new PumpEnactResult().success(false).enacted(false)
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_cant_read_tbr));
|
||||
|
@ -1133,22 +1230,35 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
Boolean response = (Boolean)responseTask2.returnData;
|
||||
|
||||
if (response) {
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - Cancel TBR successful.");
|
||||
|
||||
} else {
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - Cancel TBR failed.");
|
||||
}
|
||||
|
||||
finishAction("TBR");
|
||||
|
||||
return new PumpEnactResult().success(response).enacted(response);
|
||||
if (response) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - Cancel TBR successful.");
|
||||
|
||||
TemporaryBasal tempBasal = new TemporaryBasal() //
|
||||
.date(System.currentTimeMillis()) //
|
||||
.duration(0) //
|
||||
.source(Source.USER);
|
||||
|
||||
TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempBasal);
|
||||
|
||||
return new PumpEnactResult().success(response).enacted(response) //
|
||||
.isTempCancel(true);
|
||||
} else {
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - Cancel TBR failed.");
|
||||
|
||||
return new PumpEnactResult().success(response).enacted(response) //
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_cant_cancel_tbr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setNewBasalProfile(Profile profile) {
|
||||
LOG.error(getLogPrefix() + "setNewBasalProfile - WIP.");
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setNewBasalProfile");
|
||||
|
||||
setRefreshButtonEnabled(false);
|
||||
|
||||
|
@ -1180,9 +1290,15 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
Boolean response = (Boolean)responseTask.returnData;
|
||||
|
||||
LOG.info(getLogPrefix() + "Basal Profile was set: " + response);
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "Basal Profile was set: " + response);
|
||||
|
||||
return new PumpEnactResult().success(response).enacted(response);
|
||||
if (response) {
|
||||
return new PumpEnactResult().success(response).enacted(response);
|
||||
} else {
|
||||
return new PumpEnactResult().success(response).enacted(response) //
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_basal_profile_could_not_be_set));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1205,7 +1321,6 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
}
|
||||
|
||||
return stringBuilder.length() == 0 ? null : stringBuilder.toString();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1236,28 +1351,26 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
// OPERATIONS not supported by Pump or Plugin
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
|
||||
LOG.error("MedtronicPumpPlugin::setExtendedBolus NOT SUPPORTED.");
|
||||
return OPERATION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PumpEnactResult cancelExtendedBolus() {
|
||||
LOG.warn("cancelExtendedBolus - operation not supported.");
|
||||
return getOperationNotSupportedWithCustomText(R.string.medtronic_cmd_cancel_bolus_not_supported);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile,
|
||||
boolean enforceNew) {
|
||||
LOG.error("setTempBasalPercent NOT IMPLEMENTED.");
|
||||
// we will never come here unless somebody has played with configuration in PumpType
|
||||
return OPERATION_NOT_SUPPORTED;
|
||||
}
|
||||
// @Override
|
||||
// public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
|
||||
// LOG.error("MedtronicPumpPlugin::setExtendedBolus NOT SUPPORTED.");
|
||||
// return OPERATION_NOT_SUPPORTED;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Override
|
||||
// public PumpEnactResult cancelExtendedBolus() {
|
||||
// LOG.warn("cancelExtendedBolus - operation not supported.");
|
||||
// return getOperationNotSupportedWithCustomText(R.string.medtronic_cmd_cancel_bolus_not_supported);
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile,
|
||||
// boolean enforceNew) {
|
||||
// LOG.error("setTempBasalPercent NOT IMPLEMENTED.");
|
||||
// // we will never come here unless somebody has played with configuration in PumpType
|
||||
// return OPERATION_NOT_SUPPORTED;
|
||||
// }
|
||||
|
||||
// // we don't loadTDD. TDD is read from Pump History
|
||||
// @Override
|
||||
|
|
|
@ -13,6 +13,7 @@ import android.os.SystemClock;
|
|||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkConst;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RFSpy;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkCommunicationException;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.RFSpyResponse;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.RLMessage;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.RadioPacket;
|
||||
|
@ -22,12 +23,10 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.
|
|||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.WakeAndTuneTask;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.HexDump;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.data.Page;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RawHistoryPage;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryEntry;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryResult;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.ButtonPressCarelinkMessageBody;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.CarelinkLongMessageBody;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.CarelinkShortMessageBody;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.GetHistoryPageCarelinkMessageBody;
|
||||
|
@ -42,7 +41,6 @@ import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.TempBasalPair;
|
|||
import info.nightscout.androidaps.plugins.PumpMedtronic.defs.MedtronicCommandType;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.defs.MedtronicDeviceType;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.defs.PumpDeviceState;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.service.RileyLinkMedtronicService;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
|
@ -54,8 +52,9 @@ import info.nightscout.utils.SP;
|
|||
public class MedtronicCommunicationManager extends RileyLinkCommunicationManager {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MedtronicCommunicationManager.class);
|
||||
private static final int MAX_COMMAND_RETRIES = 2;
|
||||
private static final int MAX_COMMAND_TRIES = 3;
|
||||
private static final int DEFAULT_TIMEOUT = 2000;
|
||||
private static final long RILEYLINK_TIMEOUT = 15 * 60 * 1000; // 15 min
|
||||
|
||||
static MedtronicCommunicationManager medtronicCommunicationManager;
|
||||
String errorMessage;
|
||||
|
@ -121,17 +120,51 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
for (int retry = 0; retry < 5; retry++) {
|
||||
|
||||
LOG.error("isDeviceReachable. Waking pump... " + (retry != 0 ? " (retry " + retry + ")" : ""));
|
||||
LOG.debug("isDeviceReachable. Waking pump... " + (retry != 0 ? " (retry " + retry + ")" : ""));
|
||||
|
||||
byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData); // simple
|
||||
RFSpyResponse rfSpyResponse = rfspy.transmitThenReceive(new RadioPacket(pumpMsgContent), (byte)0,
|
||||
(byte)200, (byte)0, (byte)0, 25000, (byte)0);
|
||||
LOG.info("wakeup: raw response is " + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
boolean connected = connectToDevice();
|
||||
|
||||
if (connected)
|
||||
return true;
|
||||
|
||||
SystemClock.sleep(1000);
|
||||
|
||||
}
|
||||
|
||||
if (state != PumpDeviceState.PumpUnreachable)
|
||||
MedtronicUtil.setPumpDeviceState(PumpDeviceState.PumpUnreachable);
|
||||
|
||||
if (!canPreventTuneUp) {
|
||||
|
||||
long diff = System.currentTimeMillis() - MedtronicUtil.getPumpStatus().lastConnection;
|
||||
|
||||
if (diff > RILEYLINK_TIMEOUT) {
|
||||
ServiceTaskExecutor.startTask(new WakeAndTuneTask());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private boolean connectToDevice() {
|
||||
|
||||
PumpDeviceState state = MedtronicUtil.getPumpDeviceState();
|
||||
|
||||
byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData); // simple
|
||||
RFSpyResponse rfSpyResponse = rfspy.transmitThenReceive(new RadioPacket(pumpMsgContent), (byte)0, (byte)200,
|
||||
(byte)0, (byte)0, 25000, (byte)0);
|
||||
LOG.info("wakeup: raw response is " + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
|
||||
if (rfSpyResponse.wasTimeout()) {
|
||||
LOG.error("isDeviceReachable. Failed to find pump (timeout).");
|
||||
} else if (rfSpyResponse.looksLikeRadioPacket()) {
|
||||
RadioResponse radioResponse = new RadioResponse();
|
||||
|
||||
try {
|
||||
|
||||
radioResponse.init(rfSpyResponse.getRaw());
|
||||
|
||||
if (rfSpyResponse.wasTimeout()) {
|
||||
LOG.error("isDeviceReachable. Failed to find pump (timeout).");
|
||||
} else if (rfSpyResponse.looksLikeRadioPacket()) {
|
||||
RadioResponse radioResponse = new RadioResponse(rfSpyResponse.getRaw());
|
||||
if (radioResponse.isValid()) {
|
||||
|
||||
PumpMessage pumpResponse = createResponseMessage(radioResponse.getPayload(), PumpMessage.class);
|
||||
|
@ -175,20 +208,16 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
LOG.warn("isDeviceReachable. Failed to parse radio response: "
|
||||
+ ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
}
|
||||
} else {
|
||||
LOG.warn("isDeviceReachable. Unknown response: " + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
LOG.warn("isDeviceReachable. Failed to decode radio response: "
|
||||
+ ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
}
|
||||
|
||||
SystemClock.sleep(1000);
|
||||
|
||||
} else {
|
||||
LOG.warn("isDeviceReachable. Unknown response: " + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
}
|
||||
|
||||
if (state != PumpDeviceState.PumpUnreachable)
|
||||
MedtronicUtil.setPumpDeviceState(PumpDeviceState.PumpUnreachable);
|
||||
|
||||
if (!canPreventTuneUp)
|
||||
ServiceTaskExecutor.startTask(new WakeAndTuneTask());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -242,7 +271,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
|
||||
// FIXME remove debugs - Andy
|
||||
private PumpMessage runCommandWithArgs(PumpMessage msg) {
|
||||
private PumpMessage runCommandWithArgs(PumpMessage msg) throws RileyLinkCommunicationException {
|
||||
|
||||
if (debugSetCommands)
|
||||
LOG.debug("Run command with Args: ");
|
||||
|
@ -267,75 +296,75 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
private PumpMessage runCommandWithArgsLong(MedtronicCommandType commandType, byte[] content) {
|
||||
// @Deprecated
|
||||
// private PumpMessage runCommandWithArgsLong(MedtronicCommandType commandType, byte[] content) {
|
||||
//
|
||||
// LOG.debug("Run command with Args (Long): {}", commandType.name());
|
||||
//
|
||||
// PumpMessage rval = null;
|
||||
// PumpMessage shortMessage = makePumpMessage(commandType, new CarelinkShortMessageBody(new byte[] { 0 }));
|
||||
// // look for ack from short message
|
||||
// PumpMessage shortResponse = sendAndListen(shortMessage);
|
||||
//
|
||||
// if (shortResponse.commandType != MedtronicCommandType.CommandACK) {
|
||||
// LOG.error("runCommandWithArgs: Pump did not ack Attention packet");
|
||||
//
|
||||
// return new PumpMessage("No ACK after start message.");
|
||||
// }
|
||||
//
|
||||
// int start = 0;
|
||||
// int frameNr = 1;
|
||||
// int len = 0;
|
||||
//
|
||||
// do {
|
||||
//
|
||||
// if (start == 0)
|
||||
// LOG.debug("Run command with Args(Long): Got ACK response for Attention packet");
|
||||
// else
|
||||
// LOG.debug("Run command with Args(Long): Got ACK response for frame #{}", (frameNr - 1));
|
||||
//
|
||||
// if (start + 64 > content.length) {
|
||||
// len = content.length - start;
|
||||
//
|
||||
// if (len == 0)
|
||||
// break;
|
||||
// } else {
|
||||
// len = 64;
|
||||
// }
|
||||
//
|
||||
// byte frame[] = new byte[65];
|
||||
//
|
||||
// frame[0] = (byte)frameNr;
|
||||
//
|
||||
// System.arraycopy(content, start, frame, 1, len);
|
||||
//
|
||||
// PumpMessage msg = makePumpMessage(commandType, new CarelinkLongMessageBody(frame));
|
||||
//
|
||||
// rval = sendAndListen(msg);
|
||||
//
|
||||
// if (rval.commandType != MedtronicCommandType.CommandACK) {
|
||||
// LOG.error("runCommandWithArgs(Long): Pump did not ACK frame #{}", frameNr);
|
||||
//
|
||||
// return new PumpMessage("No ACK after frame #" + frameNr);
|
||||
// }
|
||||
//
|
||||
// if (len != 64) {
|
||||
// LOG.debug("Run command with Args(Long): Got ACK response for frame #{}", (frameNr));
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// start += 64;
|
||||
// frameNr++;
|
||||
//
|
||||
// } while (true);
|
||||
//
|
||||
// return rval;
|
||||
//
|
||||
// // return new PumpMessage("No ACK");
|
||||
// }
|
||||
|
||||
LOG.debug("Run command with Args (Long): {}", commandType.name());
|
||||
|
||||
PumpMessage rval = null;
|
||||
PumpMessage shortMessage = makePumpMessage(commandType, new CarelinkShortMessageBody(new byte[] { 0 }));
|
||||
// look for ack from short message
|
||||
PumpMessage shortResponse = sendAndListen(shortMessage);
|
||||
|
||||
if (shortResponse.commandType != MedtronicCommandType.CommandACK) {
|
||||
LOG.error("runCommandWithArgs: Pump did not ack Attention packet");
|
||||
|
||||
return new PumpMessage("No ACK after start message.");
|
||||
}
|
||||
|
||||
int start = 0;
|
||||
int frameNr = 1;
|
||||
int len = 0;
|
||||
|
||||
do {
|
||||
|
||||
if (start == 0)
|
||||
LOG.debug("Run command with Args(Long): Got ACK response for Attention packet");
|
||||
else
|
||||
LOG.debug("Run command with Args(Long): Got ACK response for frame #{}", (frameNr - 1));
|
||||
|
||||
if (start + 64 > content.length) {
|
||||
len = content.length - start;
|
||||
|
||||
if (len == 0)
|
||||
break;
|
||||
} else {
|
||||
len = 64;
|
||||
}
|
||||
|
||||
byte frame[] = new byte[65];
|
||||
|
||||
frame[0] = (byte)frameNr;
|
||||
|
||||
System.arraycopy(content, start, frame, 1, len);
|
||||
|
||||
PumpMessage msg = makePumpMessage(commandType, new CarelinkLongMessageBody(frame));
|
||||
|
||||
rval = sendAndListen(msg);
|
||||
|
||||
if (rval.commandType != MedtronicCommandType.CommandACK) {
|
||||
LOG.error("runCommandWithArgs(Long): Pump did not ACK frame #{}", frameNr);
|
||||
|
||||
return new PumpMessage("No ACK after frame #" + frameNr);
|
||||
}
|
||||
|
||||
if (len != 64) {
|
||||
LOG.debug("Run command with Args(Long): Got ACK response for frame #{}", (frameNr));
|
||||
break;
|
||||
}
|
||||
|
||||
start += 64;
|
||||
frameNr++;
|
||||
|
||||
} while (true);
|
||||
|
||||
return rval;
|
||||
|
||||
// return new PumpMessage("No ACK");
|
||||
}
|
||||
|
||||
|
||||
private PumpMessage runCommandWithFrames(MedtronicCommandType commandType, List<List<Byte>> frames) {
|
||||
private PumpMessage runCommandWithFrames(MedtronicCommandType commandType, List<List<Byte>> frames)
|
||||
throws RileyLinkCommunicationException {
|
||||
|
||||
LOG.debug("Run command with Frames: {}", commandType.name());
|
||||
|
||||
|
@ -390,6 +419,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
LOG.debug("Current command: " + MedtronicUtil.getCurrentCommand());
|
||||
|
||||
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Active);
|
||||
boolean doneWithError = false;
|
||||
|
||||
for (int pageNumber = 0; pageNumber < 16; pageNumber++) {
|
||||
|
||||
|
@ -401,7 +431,27 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
LOG.info("getPumpHistory: Page {}", pageNumber);
|
||||
// LOG.info("getPumpHistoryPage("+pageNumber+"): "+ByteUtil.shortHexString(getHistoryMsg.getTxData()));
|
||||
// Ask the pump to transfer history (we get first frame?)
|
||||
PumpMessage firstResponse = runCommandWithArgs(getHistoryMsg);
|
||||
|
||||
PumpMessage firstResponse = null;
|
||||
boolean failed = false;
|
||||
|
||||
for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) {
|
||||
|
||||
try {
|
||||
firstResponse = runCommandWithArgs(getHistoryMsg);
|
||||
failed = false;
|
||||
break;
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
LOG.error("First call for PumpHistory failed (retry={})", retries);
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping);
|
||||
return pumpTotalResult;
|
||||
}
|
||||
|
||||
// LOG.info("getPumpHistoryPage("+pageNumber+"): " + ByteUtil.shortHexString(firstResponse.getContents()));
|
||||
|
||||
PumpMessage ackMsg = makePumpMessage(MedtronicCommandType.CommandACK, new PumpAckMessageBody());
|
||||
|
@ -426,6 +476,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
rawHistoryPage.appendData(currentResponse.getFrameData());
|
||||
// RileyLinkMedtronicService.getInstance().announceProgress(
|
||||
// ((100 / 16) * currentResponse.getFrameNumber() + 1));
|
||||
MedtronicUtil.setCurrentCommand(MedtronicCommandType.GetHistoryData, pageNumber,
|
||||
currentResponse.getFrameNumber());
|
||||
|
||||
LOG.info("getPumpHistory: Got frame {} of Page {}", currentResponse.getFrameNumber(), pageNumber);
|
||||
// Do we need to ask for the next frame?
|
||||
|
@ -449,26 +501,49 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
"getPumpHistory: 6 failures in attempting to download frame {} of page {}, giving up.",
|
||||
expectedFrameNum, pageNumber);
|
||||
done = true; // failure completion.
|
||||
doneWithError = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
// ask for next frame
|
||||
PumpMessage nextMsg = sendAndListen(ackMsg);
|
||||
currentResponse = new GetHistoryPageCarelinkMessageBody(nextMsg.getMessageBody().getTxData());
|
||||
PumpMessage nextMsg = null;
|
||||
|
||||
for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) {
|
||||
|
||||
try {
|
||||
nextMsg = sendAndListen(ackMsg);
|
||||
break;
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
LOG.error("Problem acknowledging frame response. (retry={})", retries);
|
||||
}
|
||||
}
|
||||
|
||||
if (nextMsg != null)
|
||||
currentResponse = new GetHistoryPageCarelinkMessageBody(nextMsg.getMessageBody().getTxData());
|
||||
else
|
||||
LOG.error("We couldn't acknowledge frame from pump, aborting operation.");
|
||||
}
|
||||
}
|
||||
|
||||
if (rawHistoryPage.getLength() != 1024) {
|
||||
LOG.warn("getPumpHistory: short page. Expected length of 1024, found length of "
|
||||
+ rawHistoryPage.getLength());
|
||||
doneWithError = true;
|
||||
}
|
||||
|
||||
if (!rawHistoryPage.isChecksumOK()) {
|
||||
LOG.error("getPumpHistory: checksum is wrong");
|
||||
doneWithError = true;
|
||||
}
|
||||
|
||||
// TODO handle error states
|
||||
|
||||
if (doneWithError) {
|
||||
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping);
|
||||
return pumpTotalResult;
|
||||
}
|
||||
|
||||
rawHistoryPage.dumpToDebug();
|
||||
|
||||
List<PumpHistoryEntry> medtronicHistoryEntries = pumpHistoryDecoder.processPageAndCreateRecords(
|
||||
|
@ -496,86 +571,85 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public Page getPumpHistoryPage(int pageNumber) {
|
||||
RawHistoryPage rval = new RawHistoryPage();
|
||||
|
||||
if (doWakeUpBeforeCommand)
|
||||
wakeUp(receiverDeviceAwakeForMinutes, false);
|
||||
|
||||
PumpMessage getHistoryMsg = makePumpMessage(MedtronicCommandType.GetHistoryData,
|
||||
new GetHistoryPageCarelinkMessageBody(pageNumber));
|
||||
// LOG.info("getPumpHistoryPage("+pageNumber+"): "+ByteUtil.shortHexString(getHistoryMsg.getTxData()));
|
||||
// Ask the pump to transfer history (we get first frame?)
|
||||
PumpMessage firstResponse = runCommandWithArgs(getHistoryMsg);
|
||||
// LOG.info("getPumpHistoryPage("+pageNumber+"): " + ByteUtil.shortHexString(firstResponse.getContents()));
|
||||
|
||||
PumpMessage ackMsg = makePumpMessage(MedtronicCommandType.CommandACK, new PumpAckMessageBody());
|
||||
GetHistoryPageCarelinkMessageBody currentResponse = new GetHistoryPageCarelinkMessageBody(firstResponse
|
||||
.getMessageBody().getTxData());
|
||||
int expectedFrameNum = 1;
|
||||
boolean done = false;
|
||||
// while (expectedFrameNum == currentResponse.getFrameNumber()) {
|
||||
int failures = 0;
|
||||
while (!done) {
|
||||
// examine current response for problems.
|
||||
byte[] frameData = currentResponse.getFrameData();
|
||||
if ((frameData != null) && (frameData.length > 0) && currentResponse.getFrameNumber() == expectedFrameNum) {
|
||||
// success! got a frame.
|
||||
if (frameData.length != 64) {
|
||||
LOG.warn("Expected frame of length 64, got frame of length " + frameData.length);
|
||||
// but append it anyway?
|
||||
}
|
||||
// handle successful frame data
|
||||
rval.appendData(currentResponse.getFrameData());
|
||||
RileyLinkMedtronicService.getInstance().announceProgress(
|
||||
((100 / 16) * currentResponse.getFrameNumber() + 1));
|
||||
LOG.info("getPumpHistoryPage: Got frame " + currentResponse.getFrameNumber());
|
||||
// Do we need to ask for the next frame?
|
||||
if (expectedFrameNum < 16) { // This number may not be correct for pumps other than 522/722
|
||||
expectedFrameNum++;
|
||||
} else {
|
||||
done = true; // successful completion
|
||||
}
|
||||
} else {
|
||||
if (frameData == null) {
|
||||
LOG.error("null frame data, retrying");
|
||||
} else if (currentResponse.getFrameNumber() != expectedFrameNum) {
|
||||
LOG.warn("Expected frame number {}, received {} (retrying)", expectedFrameNum,
|
||||
currentResponse.getFrameNumber());
|
||||
} else if (frameData.length == 0) {
|
||||
LOG.warn("Frame has zero length, retrying");
|
||||
}
|
||||
failures++;
|
||||
if (failures == 6) {
|
||||
LOG.error("6 failures in attempting to download frame {} of page {}, giving up.", expectedFrameNum,
|
||||
pageNumber);
|
||||
done = true; // failure completion.
|
||||
}
|
||||
}
|
||||
if (!done) {
|
||||
// ask for next frame
|
||||
PumpMessage nextMsg = sendAndListen(ackMsg);
|
||||
currentResponse = new GetHistoryPageCarelinkMessageBody(nextMsg.getMessageBody().getTxData());
|
||||
}
|
||||
}
|
||||
if (rval.getLength() != 1024) {
|
||||
LOG.warn("getPumpHistoryPage: short page. Expected length of 1024, found length of " + rval.getLength());
|
||||
}
|
||||
if (!rval.isChecksumOK()) {
|
||||
LOG.error("getPumpHistoryPage: checksum is wrong");
|
||||
}
|
||||
|
||||
rval.dumpToDebug();
|
||||
|
||||
Page page = new Page();
|
||||
// page.parseFrom(rval.getData(),PumpModel.MM522);
|
||||
// FIXME
|
||||
page.parseFrom(rval.getData(), MedtronicDeviceType.Medtronic_522);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
// @Deprecated
|
||||
// public Page getPumpHistoryPage(int pageNumber) {
|
||||
// RawHistoryPage rval = new RawHistoryPage();
|
||||
//
|
||||
// if (doWakeUpBeforeCommand)
|
||||
// wakeUp(receiverDeviceAwakeForMinutes, false);
|
||||
//
|
||||
// PumpMessage getHistoryMsg = makePumpMessage(MedtronicCommandType.GetHistoryData,
|
||||
// new GetHistoryPageCarelinkMessageBody(pageNumber));
|
||||
// // LOG.info("getPumpHistoryPage("+pageNumber+"): "+ByteUtil.shortHexString(getHistoryMsg.getTxData()));
|
||||
// // Ask the pump to transfer history (we get first frame?)
|
||||
// PumpMessage firstResponse = runCommandWithArgs(getHistoryMsg);
|
||||
// // LOG.info("getPumpHistoryPage("+pageNumber+"): " + ByteUtil.shortHexString(firstResponse.getContents()));
|
||||
//
|
||||
// PumpMessage ackMsg = makePumpMessage(MedtronicCommandType.CommandACK, new PumpAckMessageBody());
|
||||
// GetHistoryPageCarelinkMessageBody currentResponse = new GetHistoryPageCarelinkMessageBody(firstResponse
|
||||
// .getMessageBody().getTxData());
|
||||
// int expectedFrameNum = 1;
|
||||
// boolean done = false;
|
||||
// // while (expectedFrameNum == currentResponse.getFrameNumber()) {
|
||||
// int failures = 0;
|
||||
// while (!done) {
|
||||
// // examine current response for problems.
|
||||
// byte[] frameData = currentResponse.getFrameData();
|
||||
// if ((frameData != null) && (frameData.length > 0) && currentResponse.getFrameNumber() == expectedFrameNum) {
|
||||
// // success! got a frame.
|
||||
// if (frameData.length != 64) {
|
||||
// LOG.warn("Expected frame of length 64, got frame of length " + frameData.length);
|
||||
// // but append it anyway?
|
||||
// }
|
||||
// // handle successful frame data
|
||||
// rval.appendData(currentResponse.getFrameData());
|
||||
// RileyLinkMedtronicService.getInstance().announceProgress(
|
||||
// ((100 / 16) * currentResponse.getFrameNumber() + 1));
|
||||
// LOG.info("getPumpHistoryPage: Got frame " + currentResponse.getFrameNumber());
|
||||
// // Do we need to ask for the next frame?
|
||||
// if (expectedFrameNum < 16) { // This number may not be correct for pumps other than 522/722
|
||||
// expectedFrameNum++;
|
||||
// } else {
|
||||
// done = true; // successful completion
|
||||
// }
|
||||
// } else {
|
||||
// if (frameData == null) {
|
||||
// LOG.error("null frame data, retrying");
|
||||
// } else if (currentResponse.getFrameNumber() != expectedFrameNum) {
|
||||
// LOG.warn("Expected frame number {}, received {} (retrying)", expectedFrameNum,
|
||||
// currentResponse.getFrameNumber());
|
||||
// } else if (frameData.length == 0) {
|
||||
// LOG.warn("Frame has zero length, retrying");
|
||||
// }
|
||||
// failures++;
|
||||
// if (failures == 6) {
|
||||
// LOG.error("6 failures in attempting to download frame {} of page {}, giving up.", expectedFrameNum,
|
||||
// pageNumber);
|
||||
// done = true; // failure completion.
|
||||
// }
|
||||
// }
|
||||
// if (!done) {
|
||||
// // ask for next frame
|
||||
// PumpMessage nextMsg = sendAndListen(ackMsg);
|
||||
// currentResponse = new GetHistoryPageCarelinkMessageBody(nextMsg.getMessageBody().getTxData());
|
||||
// }
|
||||
// }
|
||||
// if (rval.getLength() != 1024) {
|
||||
// LOG.warn("getPumpHistoryPage: short page. Expected length of 1024, found length of " + rval.getLength());
|
||||
// }
|
||||
// if (!rval.isChecksumOK()) {
|
||||
// LOG.error("getPumpHistoryPage: checksum is wrong");
|
||||
// }
|
||||
//
|
||||
// rval.dumpToDebug();
|
||||
//
|
||||
// Page page = new Page();
|
||||
// // page.parseFrom(rval.getData(),PumpModel.MM522);
|
||||
// // FIXME
|
||||
// page.parseFrom(rval.getData(), MedtronicDeviceType.Medtronic_522);
|
||||
//
|
||||
// return page;
|
||||
// }
|
||||
|
||||
// public ArrayList<Page> getAllHistoryPages() {
|
||||
// ArrayList<Page> pages = new ArrayList<>();
|
||||
|
@ -607,18 +681,17 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
|
||||
// See ButtonPressCarelinkMessageBody
|
||||
public void pressButton(int which) {
|
||||
if (doWakeUpBeforeCommand)
|
||||
wakeUp(receiverDeviceAwakeForMinutes, false);
|
||||
|
||||
PumpMessage pressButtonMessage = makePumpMessage(MedtronicCommandType.PushButton,
|
||||
new ButtonPressCarelinkMessageBody(which));
|
||||
PumpMessage resp = sendAndListen(pressButtonMessage);
|
||||
if (resp.commandType != MedtronicCommandType.CommandACK) {
|
||||
LOG.error("Pump did not ack button press.");
|
||||
}
|
||||
}
|
||||
|
||||
// public void pressButton(int which) {
|
||||
// if (doWakeUpBeforeCommand)
|
||||
// wakeUp(receiverDeviceAwakeForMinutes, false);
|
||||
//
|
||||
// PumpMessage pressButtonMessage = makePumpMessage(MedtronicCommandType.PushButton,
|
||||
// new ButtonPressCarelinkMessageBody(which));
|
||||
// PumpMessage resp = sendAndListen(pressButtonMessage);
|
||||
// if (resp.commandType != MedtronicCommandType.CommandACK) {
|
||||
// LOG.error("Pump did not ack button press.");
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public byte[] createPumpMessageContent(RLMessageType type) {
|
||||
|
@ -652,23 +725,22 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
}
|
||||
|
||||
|
||||
private PumpMessage sendAndGetResponse(MedtronicCommandType commandType) {
|
||||
private PumpMessage sendAndGetResponse(MedtronicCommandType commandType) throws RileyLinkCommunicationException {
|
||||
|
||||
return sendAndGetResponse(commandType, null, DEFAULT_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
private PumpMessage sendAndGetResponse(MedtronicCommandType commandType, int timeoutMs) {
|
||||
|
||||
return sendAndGetResponse(commandType, null, timeoutMs);
|
||||
}
|
||||
|
||||
|
||||
private PumpMessage sendAndGetResponse(MedtronicCommandType commandType, byte[] bodyData) {
|
||||
|
||||
return sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT);
|
||||
}
|
||||
|
||||
// private PumpMessage sendAndGetResponse(MedtronicCommandType commandType, int timeoutMs) {
|
||||
//
|
||||
// return sendAndGetResponse(commandType, null, timeoutMs);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private PumpMessage sendAndGetResponse(MedtronicCommandType commandType, byte[] bodyData) {
|
||||
//
|
||||
// return sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Main wrapper method for sending data - (for getting responses)
|
||||
|
@ -678,7 +750,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
* @param timeoutMs
|
||||
* @return
|
||||
*/
|
||||
private PumpMessage sendAndGetResponse(MedtronicCommandType commandType, byte[] bodyData, int timeoutMs) {
|
||||
private PumpMessage sendAndGetResponse(MedtronicCommandType commandType, byte[] bodyData, int timeoutMs)
|
||||
throws RileyLinkCommunicationException {
|
||||
// wakeUp
|
||||
if (doWakeUpBeforeCommand)
|
||||
wakeUp(receiverDeviceAwakeForMinutes, false);
|
||||
|
@ -702,13 +775,13 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
}
|
||||
|
||||
|
||||
protected PumpMessage sendAndListen(RLMessage msg) {
|
||||
protected PumpMessage sendAndListen(RLMessage msg) throws RileyLinkCommunicationException {
|
||||
return sendAndListen(msg, 4000); // 2000
|
||||
}
|
||||
|
||||
|
||||
// All pump communications go through this function.
|
||||
protected PumpMessage sendAndListen(RLMessage msg, int timeout_ms) {
|
||||
protected PumpMessage sendAndListen(RLMessage msg, int timeout_ms) throws RileyLinkCommunicationException {
|
||||
return sendAndListen(msg, timeout_ms, PumpMessage.class);
|
||||
}
|
||||
|
||||
|
@ -721,23 +794,30 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
private Object sendAndGetResponseWithCheck(MedtronicCommandType commandType, byte[] bodyData) {
|
||||
|
||||
for (int retries = 0; retries < MAX_COMMAND_RETRIES; retries++) {
|
||||
for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) {
|
||||
|
||||
PumpMessage response = sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT
|
||||
+ (DEFAULT_TIMEOUT * retries));
|
||||
try {
|
||||
PumpMessage response = null;
|
||||
|
||||
String check = checkResponseContent(response, commandType.commandDescription, commandType.expectedLength);
|
||||
response = sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
|
||||
|
||||
if (check == null) {
|
||||
String check = checkResponseContent(response, commandType.commandDescription,
|
||||
commandType.expectedLength);
|
||||
|
||||
Object dataResponse = medtronicConverter.convertResponse(commandType, response.getRawContent());
|
||||
if (check == null) {
|
||||
|
||||
LOG.debug("Converted response for {} is {}.", commandType.name(), dataResponse);
|
||||
Object dataResponse = medtronicConverter.convertResponse(commandType, response.getRawContent());
|
||||
|
||||
return dataResponse;
|
||||
} else {
|
||||
this.errorMessage = check;
|
||||
// return null;
|
||||
LOG.debug("Converted response for {} is {}.", commandType.name(), dataResponse);
|
||||
|
||||
return dataResponse;
|
||||
} else {
|
||||
this.errorMessage = check;
|
||||
// return null;
|
||||
}
|
||||
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
LOG.warn("Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -809,65 +889,74 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
MedtronicCommandType commandType = MedtronicCommandType.GetBasalProfileSTD;
|
||||
|
||||
for (int retries = 0; retries <= MAX_COMMAND_RETRIES; retries++) {
|
||||
for (int retries = 0; retries <= MAX_COMMAND_TRIES; retries++) {
|
||||
|
||||
// create message
|
||||
PumpMessage msg;
|
||||
try {
|
||||
// create message
|
||||
PumpMessage msg;
|
||||
|
||||
// if (bodyData == null)
|
||||
msg = makePumpMessage(commandType);
|
||||
// if (bodyData == null)
|
||||
msg = makePumpMessage(commandType);
|
||||
|
||||
// send and wait for response
|
||||
PumpMessage response = sendAndListen(msg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
|
||||
// send and wait for response
|
||||
PumpMessage response = null;
|
||||
|
||||
// LOG.debug("1st Response: " + HexDump.toHexStringDisplayable(response.getRawContent()));
|
||||
// LOG.debug("1st Response: " + HexDump.toHexStringDisplayable(response.getMessageBody().getTxData()));
|
||||
response = sendAndListen(msg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
|
||||
|
||||
String check = checkResponseContent(response, commandType.commandDescription, commandType.expectedLength);
|
||||
// LOG.debug("1st Response: " + HexDump.toHexStringDisplayable(response.getRawContent()));
|
||||
// LOG.debug("1st Response: " + HexDump.toHexStringDisplayable(response.getMessageBody().getTxData()));
|
||||
|
||||
byte[] data = null;
|
||||
String check = checkResponseContent(response, commandType.commandDescription,
|
||||
commandType.expectedLength);
|
||||
|
||||
int runs = 1;
|
||||
byte[] data = null;
|
||||
|
||||
if (check == null) {
|
||||
int runs = 1;
|
||||
|
||||
data = response.getRawContent();
|
||||
if (check == null) {
|
||||
|
||||
PumpMessage ackMsg = makePumpMessage(MedtronicCommandType.CommandACK, new PumpAckMessageBody());
|
||||
data = response.getRawContent();
|
||||
|
||||
while (checkIfWeHaveMoreData(commandType, response, data)) {
|
||||
PumpMessage ackMsg = makePumpMessage(MedtronicCommandType.CommandACK, new PumpAckMessageBody());
|
||||
|
||||
runs++;
|
||||
while (checkIfWeHaveMoreData(commandType, response, data)) {
|
||||
|
||||
PumpMessage response2 = sendAndListen(ackMsg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
|
||||
runs++;
|
||||
|
||||
// LOG.debug("{} Response: {}", runs, HexDump.toHexStringDisplayable(response2.getRawContent()));
|
||||
// LOG.debug("{} Response: {}", runs,
|
||||
// HexDump.toHexStringDisplayable(response2.getMessageBody().getTxData()));
|
||||
PumpMessage response2 = sendAndListen(ackMsg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
|
||||
|
||||
String check2 = checkResponseContent(response2, commandType.commandDescription,
|
||||
commandType.expectedLength);
|
||||
// LOG.debug("{} Response: {}", runs,
|
||||
// HexDump.toHexStringDisplayable(response2.getRawContent()));
|
||||
// LOG.debug("{} Response: {}", runs,
|
||||
// HexDump.toHexStringDisplayable(response2.getMessageBody().getTxData()));
|
||||
|
||||
if (check2 == null) {
|
||||
String check2 = checkResponseContent(response2, commandType.commandDescription,
|
||||
commandType.expectedLength);
|
||||
|
||||
data = ByteUtil.concat(data, ByteUtil.substring(response2.getMessageBody().getTxData(), 1));
|
||||
if (check2 == null) {
|
||||
|
||||
} else {
|
||||
this.errorMessage = check;
|
||||
data = ByteUtil.concat(data, ByteUtil.substring(response2.getMessageBody().getTxData(), 1));
|
||||
|
||||
} else {
|
||||
this.errorMessage = check;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
errorMessage = check;
|
||||
}
|
||||
|
||||
} else {
|
||||
errorMessage = check;
|
||||
BasalProfile basalProfile = (BasalProfile)medtronicConverter.convertResponse(commandType, data);
|
||||
|
||||
LOG.debug("Converted response for {} is {}.", commandType.name(), basalProfile);
|
||||
|
||||
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping);
|
||||
|
||||
return basalProfile;
|
||||
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
LOG.warn("Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
|
||||
}
|
||||
|
||||
BasalProfile basalProfile = (BasalProfile)medtronicConverter.convertResponse(commandType, data);
|
||||
|
||||
LOG.debug("Converted response for {} is {}.", commandType.name(), basalProfile);
|
||||
|
||||
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping);
|
||||
|
||||
return basalProfile;
|
||||
}
|
||||
|
||||
LOG.warn("Error reading profile in max retries.");
|
||||
|
@ -933,45 +1022,46 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
LOG.info("setBolus: " + units);
|
||||
|
||||
if (this.doWakeUpBeforeCommand)
|
||||
wakeUp(false);
|
||||
return setCommand(MedtronicCommandType.SetBolus, MedtronicUtil.getBolusStrokes(units));
|
||||
|
||||
byte[] body = MedtronicUtil.getBolusStrokes(units);
|
||||
|
||||
if (debugSetCommands)
|
||||
LOG.debug("Set Bolus: Body - {}", HexDump.toHexStringDisplayable(body));
|
||||
|
||||
PumpMessage msg = makePumpMessage(MedtronicCommandType.SetBolus, //
|
||||
new CarelinkLongMessageBody(body));
|
||||
|
||||
PumpMessage pumpMessage = runCommandWithArgs(msg);
|
||||
|
||||
if (debugSetCommands)
|
||||
LOG.debug("Set Bolus: {}", pumpMessage.getResponseContent());
|
||||
|
||||
return pumpMessage.commandType == MedtronicCommandType.CommandACK;
|
||||
}
|
||||
|
||||
|
||||
public boolean setTBR(TempBasalPair tbr) {
|
||||
|
||||
if (this.doWakeUpBeforeCommand)
|
||||
wakeUp(false);
|
||||
LOG.info("setTBR: " + tbr.getDescription());
|
||||
|
||||
byte[] body = tbr.getAsRawData();
|
||||
return setCommand(MedtronicCommandType.SetTemporaryBasal, tbr.getAsRawData());
|
||||
}
|
||||
|
||||
if (debugSetCommands)
|
||||
LOG.debug("Set TBR: Body - {}", HexDump.toHexStringDisplayable(body));
|
||||
|
||||
PumpMessage msg = makePumpMessage(MedtronicCommandType.SetTemporaryBasal, //
|
||||
new CarelinkLongMessageBody(tbr.getAsRawData()));
|
||||
private boolean setCommand(MedtronicCommandType commandType, byte[] body) {
|
||||
|
||||
PumpMessage pumpMessage = runCommandWithArgs(msg);
|
||||
for (int retries = 0; retries <= MAX_COMMAND_TRIES; retries++) {
|
||||
|
||||
if (debugSetCommands)
|
||||
LOG.debug("Set TBR: {}", pumpMessage.getResponseContent());
|
||||
try {
|
||||
if (this.doWakeUpBeforeCommand)
|
||||
wakeUp(false);
|
||||
|
||||
return pumpMessage.commandType == MedtronicCommandType.CommandACK;
|
||||
if (debugSetCommands)
|
||||
LOG.debug("{}: Body - {}", commandType.getCommandDescription(),
|
||||
HexDump.toHexStringDisplayable(body));
|
||||
|
||||
PumpMessage msg = makePumpMessage(commandType, new CarelinkLongMessageBody(body));
|
||||
|
||||
PumpMessage pumpMessage = runCommandWithArgs(msg);
|
||||
|
||||
if (debugSetCommands)
|
||||
LOG.debug("{}: {}", commandType.getCommandDescription(), pumpMessage.getResponseContent());
|
||||
|
||||
return pumpMessage.commandType == MedtronicCommandType.CommandACK;
|
||||
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
LOG.warn("Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -992,11 +1082,23 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
List<List<Byte>> basalProfileFrames = MedtronicUtil.getBasalProfileFrames(basalProfile.getRawData());
|
||||
|
||||
PumpMessage responseMessage = runCommandWithFrames(MedtronicCommandType.SetBasalProfileSTD, basalProfileFrames);
|
||||
for (int retries = 0; retries <= MAX_COMMAND_TRIES; retries++) {
|
||||
|
||||
// LOG.debug("Set Basal Profile: {}", HexDump.toHexStringDisplayable(responseMessage.getRawContent()));
|
||||
// PumpMessage responseMessage = null;
|
||||
try {
|
||||
PumpMessage responseMessage = runCommandWithFrames(MedtronicCommandType.SetBasalProfileSTD,
|
||||
basalProfileFrames);
|
||||
|
||||
return responseMessage.commandType == MedtronicCommandType.CommandACK;
|
||||
return responseMessage.commandType == MedtronicCommandType.CommandACK;
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
LOG.warn("Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
|
||||
}
|
||||
|
||||
// LOG.debug("Set Basal Profile: {}", HexDump.toHexStringDisplayable(responseMessage.getRawContent()));
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1006,33 +1108,31 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
// TODO test
|
||||
|
||||
// TODO remove, we will see state from History
|
||||
public PumpMessage getPumpState() {
|
||||
PumpMessage response = sendAndGetResponse(MedtronicCommandType.PumpState);
|
||||
|
||||
byte[] data = response.getRawContent();
|
||||
|
||||
LOG.debug("Pump State: {}", HexDump.toHexStringDisplayable(data));
|
||||
|
||||
// 3 TBR running ?
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// public PumpMessage getPumpState() {
|
||||
// PumpMessage response = sendAndGetResponse(MedtronicCommandType.PumpState);
|
||||
//
|
||||
// byte[] data = response.getRawContent();
|
||||
//
|
||||
// LOG.debug("Pump State: {}", HexDump.toHexStringDisplayable(data));
|
||||
//
|
||||
// // 3 TBR running ?
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// TODO remove, we will see bolus status from History
|
||||
public PumpMessage getBolusStatus() {
|
||||
PumpMessage response = sendAndGetResponse(MedtronicCommandType.SetBolus, new byte[] { 0x03, 0x00, 0x00, 0x00 },
|
||||
4000);
|
||||
|
||||
byte[] data = response.getRawContent();
|
||||
|
||||
LOG.debug("Detect bolus: {}", HexDump.toHexStringDisplayable(data));
|
||||
|
||||
// 3 TBR running ?
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// public PumpMessage getBolusStatus() {
|
||||
// PumpMessage response = sendAndGetResponse(MedtronicCommandType.SetBolus, new byte[] { 0x03, 0x00, 0x00, 0x00 },
|
||||
// 4000);
|
||||
//
|
||||
// byte[] data = response.getRawContent();
|
||||
//
|
||||
// LOG.debug("Detect bolus: {}", HexDump.toHexStringDisplayable(data));
|
||||
//
|
||||
// // 3 TBR running ?
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
|
||||
public PumpMessage cancelBolus() {
|
||||
// ? maybe suspend and resume
|
||||
|
|
|
@ -248,7 +248,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
return decodeDailyTotals(entry); // Not supported at the moment
|
||||
|
||||
case SelectBasalProfile:
|
||||
return RecordDecodeStatus.Ignored; // Not supported at the moment
|
||||
return RecordDecodeStatus.OK; // Not supported at the moment
|
||||
|
||||
// WORK IN PROGRESS
|
||||
|
||||
|
@ -782,6 +782,10 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
int dayOfMonth = dt[0] & 0x1F;
|
||||
int year = 2000 + (ByteUtil.asUINT8(dt[1]) & 0x7F);
|
||||
|
||||
int hour = 0;
|
||||
int minutes = 0;
|
||||
int seconds = 0;
|
||||
|
||||
// LocalDate rval = new LocalDate(year, month, dayOfMonth);
|
||||
|
||||
// int dayOfMonth = dt[0] & 0x1F;
|
||||
|
@ -794,17 +798,22 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
|
||||
if (dayOfMonth == 32) {
|
||||
// FIXME remove
|
||||
LOG.debug("Entry: {} = [{}] {}", entry.getEntryType().name(), ByteUtil.getHex(entry.getRawData()),
|
||||
entry);
|
||||
LOG.debug("Entry: Day 32 {} = [{}] {}", entry.getEntryType().name(),
|
||||
ByteUtil.getHex(entry.getRawData()), entry);
|
||||
}
|
||||
|
||||
if (entry.getEntryType() == PumpHistoryEntryType.EndResultTotals) {
|
||||
atdate = new LocalDateTime(year, month, dayOfMonth, 23, 59, 59);
|
||||
hour = 23;
|
||||
minutes = 59;
|
||||
seconds = 59;
|
||||
} else {
|
||||
atdate = new LocalDateTime(year, month, dayOfMonth, 0, 0);
|
||||
}
|
||||
|
||||
entry.setLocalDateTime(atdate);
|
||||
entry.setAtechDateTime(DateTimeUtil.toATechDate(year, month, dayOfMonth, hour, minutes, seconds));
|
||||
|
||||
} else {
|
||||
LOG.warn("Unknown datetime format: " + entry.getDateTimeLength());
|
||||
}
|
||||
|
@ -824,16 +833,4 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
|||
return year;
|
||||
}
|
||||
|
||||
// WRITE DATA
|
||||
|
||||
// private void writeData(PumpBaseType baseType, CodeEnumWithTranslation subType, ATechDate aTechDate) {
|
||||
// this.pumpValuesWriter.writeObject(baseType.name() + "_" + subType.getName(), aTechDate);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private void writeData(PumpBaseType baseType, CodeEnumWithTranslation subType, String value, ATechDate aTechDate)
|
||||
// {
|
||||
// this.pumpValuesWriter.writeObject(baseType.name() + "_" + subType.getName(), aTechDate, value);
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -193,14 +193,14 @@ public class MedtronicUIPostprocessor {
|
|||
checkValue = settings.get("PCFG_MAX_BOLUS");
|
||||
|
||||
if (!MedtronicUtil.isSame(Double.parseDouble(checkValue.value), pumpStatus.maxBolus)) {
|
||||
LOG.error("Wrong Max Bolus set on Pump (must be {}).", pumpStatus.maxBolus);
|
||||
LOG.error("Wrong Max Bolus set on Pump (current={}, required={}).", checkValue.value, pumpStatus.maxBolus);
|
||||
sendNotification(MedtronicNotificationType.PumpWrongMaxBolusSet, pumpStatus.maxBolus);
|
||||
}
|
||||
|
||||
checkValue = settings.get("PCFG_MAX_BASAL");
|
||||
|
||||
if (!MedtronicUtil.isSame(Double.parseDouble(checkValue.value), pumpStatus.maxBasal)) {
|
||||
LOG.error("Wrong Max Basal set on Pump (must be {}).", pumpStatus.maxBasal);
|
||||
LOG.error("Wrong Max Basal set on Pump (current={}, required={}).", checkValue.value, pumpStatus.maxBasal);
|
||||
sendNotification(MedtronicNotificationType.PumpWrongMaxBasalSet, pumpStatus.maxBasal);
|
||||
}
|
||||
|
||||
|
|
|
@ -88,11 +88,11 @@ public class MedtronicUITask {
|
|||
}
|
||||
break;
|
||||
|
||||
case PumpState: {
|
||||
// TODO maybe remove this, data returned is almost useless
|
||||
returnData = communicationManager.getPumpState();
|
||||
}
|
||||
break;
|
||||
// case PumpState: {
|
||||
// // TODO maybe remove this, data returned is almost useless
|
||||
// returnData = communicationManager.getPumpState();
|
||||
// }
|
||||
// break;
|
||||
|
||||
// case "RefreshData.GetBolus": {
|
||||
// returnData = communicationManager.getBolusStatus();
|
||||
|
|
|
@ -109,6 +109,7 @@ public class MedtronicHistoryData {
|
|||
}
|
||||
|
||||
|
||||
// FIXME not just 50 records, last 24 hours
|
||||
public void finalizeNewHistoryRecords() {
|
||||
|
||||
List<PumpHistoryEntry> filteredListByLastRecord = getFilteredListByLastRecord((PumpHistoryEntryType)null);
|
||||
|
@ -151,6 +152,13 @@ public class MedtronicHistoryData {
|
|||
// TODO This logic might not be working correctly
|
||||
public boolean isPumpSuspended(Boolean wasPumpSuspended) {
|
||||
|
||||
if (true)
|
||||
return false;
|
||||
|
||||
List<PumpHistoryEntry> newAndAll = new ArrayList<>();
|
||||
newAndAll.addAll(this.allHistory);
|
||||
newAndAll.addAll(this.newHistory);
|
||||
|
||||
if (wasPumpSuspended == null) { // suspension status not known
|
||||
|
||||
List<PumpHistoryEntry> items = getFilteredItems(PumpHistoryEntryType.Bolus, //
|
||||
|
@ -200,6 +208,9 @@ public class MedtronicHistoryData {
|
|||
|
||||
} else {
|
||||
|
||||
if (items.size() == 0)
|
||||
return wasPumpSuspended == null ? false : wasPumpSuspended;
|
||||
|
||||
PumpHistoryEntry pumpHistoryEntry = items.get(0);
|
||||
|
||||
if (pumpHistoryEntry.getEntryType() == PumpHistoryEntryType.NoDeliveryAlarm || //
|
||||
|
|
|
@ -115,6 +115,61 @@ public class DailyTotalsDTO {
|
|||
|
||||
private void decodeData523(byte[] data) {
|
||||
LOG.debug("Can't decode DailyTotals523: Body={}", ByteUtil.getHex(data));
|
||||
|
||||
// 0x6E 0xB1 0x92
|
||||
// 0x05 0x00 0x80 0x00 0x00 0x01 0x00 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00
|
||||
// 0x24 0x00 0x00 0x00 0x00 0x00 0x26 0x01 0x00 0x00 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
|
||||
// 0x05 0x00 0x80 0x00 0x00 0x01 0x00 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00
|
||||
// 0x24 0x00 0x00 0x00 0x00 0x00 0x26 0x01 0x00 0x00
|
||||
// 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
|
||||
// 19:31:40.314 [Thread-47]
|
||||
// D/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
|
||||
// [MedtronicPumpHistoryDecoder.decodeDailyTotals():447]: PumpHistoryRecord [type=DailyTotals523 [110, 0x6E],
|
||||
// DT: 16.11.2018 00:00:00, length=1,2,49(52), data={Raw Data=0x6E 0xB0 0x92 0x05 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// 0x00 0x00 0x55 0x00 0x55 0x64 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}]
|
||||
// 19:31:40.318 [Thread-47] D/info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.DailyTotalsDTO:
|
||||
// [DailyTotalsDTO.decodeData523():117]: Can't decode DailyTotals523: Body=0x05 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// 0x00 0x00 0x55 0x00 0x55 0x64 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// 19:31:40.320 [Thread-47]
|
||||
// W/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
|
||||
// [MedtronicPumpHistoryDecoder.createRecords():181]: #0 WIP PumpHistoryRecord [type=DailyTotals523 [110, 0x6E],
|
||||
// DT: 16.11.2018 00:00:00, length=1,2,49(52), data={Raw Data=0x6E 0xB0 0x92 0x05 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// 0x00 0x00 0x55 0x00 0x55 0x64 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}]
|
||||
// 19:31:40.341 [Thread-47]
|
||||
// D/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
|
||||
// [MedtronicPumpHistoryDecoder.decodeDateTime():793]: DT: 2018 11 17
|
||||
// 19:31:40.342 [Thread-47]
|
||||
// D/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
|
||||
// [MedtronicPumpHistoryDecoder.decodeDateTime():793]: DT: 2018 11 17
|
||||
// 19:31:40.342 [Thread-47]
|
||||
// D/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
|
||||
// [MedtronicPumpHistoryDecoder.decodeDailyTotals():446]: DailyTotals523 - 0x6E 0xB1 0x92 0x05 0x00 0x80 0x00
|
||||
// 0x00 0x01 0x00 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00 0x24 0x00 0x00 0x00 0x00 0x00 0x26
|
||||
// 0x01 0x00 0x00 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// 0x00
|
||||
// 19:31:40.343 [Thread-47]
|
||||
// D/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
|
||||
// [MedtronicPumpHistoryDecoder.decodeDailyTotals():447]: PumpHistoryRecord [type=DailyTotals523 [110, 0x6E],
|
||||
// DT: 17.11.2018 00:00:00, length=1,2,49(52), data={Raw Data=0x6E 0xB1 0x92 0x05 0x00 0x80 0x00 0x00 0x01 0x00
|
||||
// 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00 0x24 0x00 0x00 0x00 0x00 0x00 0x26 0x01 0x00 0x00
|
||||
// 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}]
|
||||
// 19:31:40.343 [Thread-47] D/info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.DailyTotalsDTO:
|
||||
// [DailyTotalsDTO.decodeData523():117]: Can't decode DailyTotals523: Body=0x05 0x00 0x80 0x00 0x00 0x01 0x00
|
||||
// 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00 0x24 0x00 0x00 0x00 0x00 0x00 0x26 0x01 0x00 0x00
|
||||
// 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// 19:31:40.344 [Thread-47]
|
||||
// W/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
|
||||
// [MedtronicPumpHistoryDecoder.createRecords():181]: #60 WIP PumpHistoryRecord [type=DailyTotals523 [110,
|
||||
// 0x6E], DT: 17.11.2018 00:00:00, length=1,2,49(52), data={Raw Data=0x6E 0xB1 0x92 0x05 0x00 0x80 0x00 0x00
|
||||
// 0x01 0x00 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00 0x24 0x00 0x00 0x00 0x00 0x00 0x26 0x01
|
||||
// 0x00 0x00 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// 0x00}]
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -142,6 +142,22 @@ public class TempBasalPair {
|
|||
}
|
||||
|
||||
|
||||
public String getDescription() {
|
||||
|
||||
String desc = "";
|
||||
|
||||
if (isPercent) {
|
||||
desc = "Rate=" + insulinRate + "%";
|
||||
} else {
|
||||
desc = "Rate=" + insulinRate + " U";
|
||||
}
|
||||
|
||||
desc += ", Duration=" + durationMinutes + " min";
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TempBasalPair [" + "Rate=" + insulinRate + ", DurationMinutes=" + durationMinutes + ", IsPercent="
|
||||
|
|
|
@ -43,10 +43,10 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
PushButton(0x5b, "Push Button", MinimedTargetType.ActionCommand, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), // 91
|
||||
|
||||
RFPowerOn(93, "RF Power On", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(
|
||||
1, 10)), //
|
||||
1, 10)), //
|
||||
|
||||
RFPowerOff(93, "RF Power Off", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(
|
||||
0, 0)), //
|
||||
0, 0)), //
|
||||
|
||||
SetSuspend(77, "Set Suspend", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(1)), //
|
||||
|
||||
|
@ -58,7 +58,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
|
||||
// 511 (InitCommand = 2, Config 7, Data = 1(+3)
|
||||
DetectBolus(75, "Detect Bolus", MinimedTargetType.InitCommand, MedtronicDeviceType.Medtronic_511, MinimedCommandParameterType.FixedParameters, getByteArray(
|
||||
0, 0, 0)), //
|
||||
0, 0, 0)), //
|
||||
|
||||
RemoteControlIds(118, "Remote Control Ids", MinimedTargetType.PumpConfiguration_NA, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
|
@ -79,7 +79,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
ReadTemporaryBasal(0x98, "Read Temporary Basal", MinimedTargetType.InitCommand, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 5), // 152
|
||||
|
||||
SetTemporaryBasal(76, "Set Temp Basal Rate (bolus detection only)", MinimedTargetType.InitCommand, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, getByteArray(
|
||||
0, 0, 0)),
|
||||
0, 0, 0)),
|
||||
// util.getCommand(MinimedCommand.SET_TEMPORARY_BASAL).allowedRetries
|
||||
// = 0;
|
||||
|
||||
|
@ -109,10 +109,10 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
GetBasalProfileSTD(146, "Get Profile Standard", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8, 1), // 146
|
||||
|
||||
GetBasalProfileA(147, "Get Profile A", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 9), // 147
|
||||
// FIXME
|
||||
// FIXME
|
||||
|
||||
GetBasalProfileB(148, "Get Profile B", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 10), // 148
|
||||
// FIXME
|
||||
// FIXME
|
||||
|
||||
SetBasalProfileSTD(0x6f, "Set Profile Standard", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8), // 111
|
||||
|
||||
|
@ -154,7 +154,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
|
||||
// Fake Commands
|
||||
|
||||
CancelTBR(), ;
|
||||
CancelTBR(),;
|
||||
|
||||
static Map<Byte, MedtronicCommandType> mapByCode;
|
||||
|
||||
|
@ -176,6 +176,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
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;
|
||||
|
@ -193,33 +194,33 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
|
||||
|
||||
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
|
||||
MinimedCommandParameterType parameterType) {
|
||||
MinimedCommandParameterType parameterType) {
|
||||
this(code, description, targetType, devices, parameterType, 64, 1, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
|
||||
MinimedCommandParameterType parameterType, int expectedLength) {
|
||||
MinimedCommandParameterType parameterType, int expectedLength) {
|
||||
this(code, description, targetType, devices, parameterType, 64, 1, 0, 0, 0, expectedLength);
|
||||
}
|
||||
|
||||
|
||||
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
|
||||
MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType) {
|
||||
MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType) {
|
||||
this(code, description, targetType, devices, parameterType, recordLength, maxRecords, 0, 0, commandType, 0);
|
||||
}
|
||||
|
||||
|
||||
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
|
||||
MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType,
|
||||
int expectedLength) {
|
||||
MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType,
|
||||
int expectedLength) {
|
||||
this(code, description, targetType, devices, parameterType, recordLength, maxRecords, 0, 0, commandType,
|
||||
expectedLength);
|
||||
expectedLength);
|
||||
}
|
||||
|
||||
|
||||
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
|
||||
MinimedCommandParameterType parameterType, byte[] cmd_params) {
|
||||
MinimedCommandParameterType parameterType, byte[] cmd_params) {
|
||||
this(code, description, targetType, devices, parameterType, 0, 1, 0, 0, 11, 0);
|
||||
|
||||
this.commandParameters = cmd_params;
|
||||
|
@ -228,7 +229,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
|
||||
|
||||
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
|
||||
MinimedCommandParameterType parameterType, byte[] cmd_params, int expectedLength) {
|
||||
MinimedCommandParameterType parameterType, byte[] cmd_params, int expectedLength) {
|
||||
this(code, description, targetType, devices, parameterType, 0, 1, 0, 0, 11, expectedLength);
|
||||
|
||||
this.commandParameters = cmd_params;
|
||||
|
@ -237,7 +238,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
|
||||
|
||||
MedtronicCommandType(int code, String description, MedtronicDeviceType devices, //
|
||||
MinimedCommandParameterType parameterType) {
|
||||
MinimedCommandParameterType parameterType) {
|
||||
|
||||
this(code, description, devices, parameterType, 64, 1, 0, null);
|
||||
}
|
||||
|
@ -245,35 +246,36 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
|
||||
// NEW
|
||||
MedtronicCommandType(int code, String description, MedtronicDeviceType devices,
|
||||
MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType) {
|
||||
MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType) {
|
||||
this(code, description, devices, parameterType, recordLength, maxRecords, 0, null);
|
||||
}
|
||||
|
||||
|
||||
// NEW
|
||||
MedtronicCommandType(int code, String description, MedtronicDeviceType devices, //
|
||||
MinimedCommandParameterType parameterType, int expectedLength) {
|
||||
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) {
|
||||
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;
|
||||
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;
|
||||
|
@ -289,9 +291,9 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
|
||||
@Deprecated
|
||||
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices, //
|
||||
MinimedCommandParameterType parameterType, int recordLength, int max_recs, int addy, //
|
||||
int addy_len, int cmd_type, int expectedLength) {
|
||||
this.commandCode = (byte)code;
|
||||
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;
|
||||
|
@ -326,7 +328,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
byte[] array = new byte[data.length];
|
||||
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
array[i] = (byte)data[i];
|
||||
array[i] = (byte) data[i];
|
||||
}
|
||||
|
||||
return array;
|
||||
|
@ -398,7 +400,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
*/
|
||||
public String getFullCommandDescription() {
|
||||
return "Command [name=" + this.name() + ", id=" + this.commandCode + ",description=" + this.commandDescription
|
||||
+ "] ";
|
||||
+ "] ";
|
||||
}
|
||||
|
||||
|
||||
|
@ -446,6 +448,15 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
return name();
|
||||
}
|
||||
|
||||
|
||||
public String getCommandDescription() {
|
||||
return this.commandDescription;
|
||||
}
|
||||
|
||||
public Integer getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public enum MinimedCommandParameterType {
|
||||
NoParameters, //
|
||||
FixedParameters, //
|
||||
|
|
|
@ -124,7 +124,7 @@ public class MedtronicPumpStatus extends PumpStatus {
|
|||
medtronicPumpMap.put("754", PumpType.Medtronic_554_754_Veo);
|
||||
|
||||
frequencies = new String[2];
|
||||
frequencies[0] = MainApp.gs(R.string.medtronic_pump_frequency_us);
|
||||
frequencies[0] = MainApp.gs(R.string.medtronic_pump_frequency_us_ca);
|
||||
frequencies[1] = MainApp.gs(R.string.medtronic_pump_frequency_worldwide);
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,8 @@ public class MedtronicPumpStatus extends PumpStatus {
|
|||
if (this.medtronicDeviceTypeMap == null)
|
||||
createMedtronicDeviceTypeMap();
|
||||
|
||||
this.errorDescription = "-";
|
||||
|
||||
String serialNr = SP.getString(MedtronicConst.Prefs.PumpSerial, null);
|
||||
|
||||
if (serialNr == null) {
|
||||
|
@ -188,6 +190,7 @@ public class MedtronicPumpStatus extends PumpStatus {
|
|||
this.errorDescription = MainApp.gs(R.string.medtronic_error_pump_frequency_invalid);
|
||||
return;
|
||||
} else {
|
||||
// if (this.pumpFrequency == null || !this.pumpFrequency.equals(pumpFrequency))
|
||||
this.pumpFrequency = pumpFrequency;
|
||||
this.isFrequencyUS = pumpFrequency.equals(frequencies[0]);
|
||||
|
||||
|
@ -195,9 +198,10 @@ public class MedtronicPumpStatus extends PumpStatus {
|
|||
RileyLinkTargetFrequency.Medtronic_US
|
||||
: RileyLinkTargetFrequency.Medtronic_WorldWide;
|
||||
|
||||
if (targetFrequency == newTargetFrequency) {
|
||||
if (targetFrequency != newTargetFrequency) {
|
||||
RileyLinkUtil.setRileyLinkTargetFrequency(newTargetFrequency);
|
||||
targetFrequencyChanged = true;
|
||||
targetFrequency = newTargetFrequency;
|
||||
// targetFrequencyChanged = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -206,11 +210,13 @@ public class MedtronicPumpStatus extends PumpStatus {
|
|||
String rileyLinkAddress = SP.getString(RileyLinkConst.Prefs.RileyLinkAddress, null);
|
||||
|
||||
if (rileyLinkAddress == null) {
|
||||
LOG.debug("RileyLink address invalid: null");
|
||||
this.errorDescription = MainApp.gs(R.string.medtronic_error_rileylink_address_invalid);
|
||||
return;
|
||||
} else {
|
||||
if (!rileyLinkAddress.matches(regexMac)) {
|
||||
this.errorDescription = MainApp.gs(R.string.medtronic_error_rileylink_address_invalid);
|
||||
LOG.debug("RileyLink address invalid: {}", rileyLinkAddress);
|
||||
} else {
|
||||
if (!rileyLinkAddress.equals(this.rileyLinkAddress)) {
|
||||
this.rileyLinkAddress = rileyLinkAddress;
|
||||
|
@ -248,13 +254,13 @@ public class MedtronicPumpStatus extends PumpStatus {
|
|||
rileyLinkAddressChanged = false;
|
||||
}
|
||||
|
||||
if (targetFrequencyChanged && !inPreInit && MedtronicUtil.getMedtronicService() != null) {
|
||||
RileyLinkUtil.setRileyLinkTargetFrequency(targetFrequency);
|
||||
RileyLinkUtil.getRileyLinkCommunicationManager().refreshRileyLinkTargetFrequency();
|
||||
targetFrequencyChanged = false;
|
||||
}
|
||||
// if (targetFrequencyChanged && !inPreInit && MedtronicUtil.getMedtronicService() != null) {
|
||||
// RileyLinkUtil.setRileyLinkTargetFrequency(targetFrequency);
|
||||
// // RileyLinkUtil.getRileyLinkCommunicationManager().refreshRileyLinkTargetFrequency();
|
||||
// targetFrequencyChanged = false;
|
||||
// }
|
||||
|
||||
return (!rileyLinkAddressChanged && !serialChanged && !targetFrequencyChanged);
|
||||
return (!rileyLinkAddressChanged && !serialChanged); // && !targetFrequencyChanged);
|
||||
}
|
||||
|
||||
|
||||
|
@ -271,7 +277,7 @@ public class MedtronicPumpStatus extends PumpStatus {
|
|||
}
|
||||
|
||||
if (val > defaultValueDouble) {
|
||||
SP.putString(MedtronicConst.Prefs.MaxBolus, defaultValue);
|
||||
SP.putString(key, defaultValue);
|
||||
val = defaultValueDouble;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,14 +10,12 @@ import android.os.Binder;
|
|||
import android.os.IBinder;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkConst;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkUtil;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RFSpy;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkBLE;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkEncodingType;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkTargetFrequency;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkServiceState;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkTargetDevice;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.RileyLinkService;
|
||||
|
@ -86,15 +84,16 @@ public class RileyLinkMedtronicService extends RileyLinkService {
|
|||
}
|
||||
|
||||
|
||||
// FIXME remove this, it needs to be set in PumpConfiguration not here
|
||||
@Override
|
||||
protected void determineRileyLinkTargetFrequency() {
|
||||
boolean hasUSFrequency = SP.getString(MedtronicConst.Prefs.PumpFrequency,
|
||||
MainApp.gs(R.string.medtronic_pump_frequency_us)).equals(MainApp.gs(R.string.medtronic_pump_frequency_us));
|
||||
|
||||
if (hasUSFrequency)
|
||||
RileyLinkUtil.setRileyLinkTargetFrequency(RileyLinkTargetFrequency.Medtronic_US);
|
||||
else
|
||||
RileyLinkUtil.setRileyLinkTargetFrequency(RileyLinkTargetFrequency.Medtronic_WorldWide);
|
||||
// boolean hasUSFrequency = SP.getString(MedtronicConst.Prefs.PumpFrequency,
|
||||
// MainApp.gs(R.string.medtronic_pump_frequency_us)).equals(MainApp.gs(R.string.medtronic_pump_frequency_us));
|
||||
//
|
||||
// if (hasUSFrequency)
|
||||
// RileyLinkUtil.setRileyLinkTargetFrequency(RileyLinkTargetFrequency.Medtronic_US);
|
||||
// else
|
||||
// RileyLinkUtil.setRileyLinkTargetFrequency(RileyLinkTargetFrequency.Medtronic_WorldWide);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package info.nightscout.androidaps.plugins.PumpMedtronic.util;
|
||||
|
||||
import org.joda.time.LocalTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.LocalTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
|
@ -71,8 +71,8 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
|
||||
|
||||
public static byte[] getByteArrayFromUnsignedShort(int shortValue, boolean returnFixedSize) {
|
||||
byte highByte = (byte)(shortValue >> 8 & 0xFF);
|
||||
byte lowByte = (byte)(shortValue & 0xFF);
|
||||
byte highByte = (byte) (shortValue >> 8 & 0xFF);
|
||||
byte lowByte = (byte) (shortValue & 0xFF);
|
||||
|
||||
if (highByte > 0) {
|
||||
return createByteArray(highByte, lowByte);
|
||||
|
@ -106,7 +106,7 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
|
||||
|
||||
public static double decodeBasalInsulin(int i) {
|
||||
return (double)i / 40.0d;
|
||||
return (double) i / 40.0d;
|
||||
}
|
||||
|
||||
|
||||
|
@ -149,7 +149,7 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
scrollRate = 1;
|
||||
}
|
||||
|
||||
int strokes = (int)(amount * ((strokesPerUnit * 1.0d) / (scrollRate * 1.0d))) * scrollRate;
|
||||
int strokes = (int) (amount * ((strokesPerUnit * 1.0d) / (scrollRate * 1.0d))) * scrollRate;
|
||||
|
||||
byte[] body = ByteUtil.fromHexString(String.format("%02x%0" + (2 * length) + "x", length, strokes));
|
||||
|
||||
|
@ -159,7 +159,7 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
|
||||
public static byte[] createCommandBody(byte[] input) {
|
||||
|
||||
return ByteUtil.concat((byte)input.length, input);
|
||||
return ByteUtil.concat((byte) input.length, input);
|
||||
}
|
||||
|
||||
|
||||
|
@ -187,7 +187,7 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
scrollRate = 2;
|
||||
}
|
||||
|
||||
int strokes = (int)(amount * (strokesPerUnit / (scrollRate * 1.0d)));
|
||||
int strokes = (int) (amount * (strokesPerUnit / (scrollRate * 1.0d)));
|
||||
|
||||
strokes *= scrollRate;
|
||||
|
||||
|
@ -198,18 +198,18 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
|
||||
public static void sendNotification(MedtronicNotificationType notificationType) {
|
||||
Notification notification = new Notification( //
|
||||
notificationType.getNotificationType(), //
|
||||
MainApp.gs(notificationType.getResourceId()), //
|
||||
notificationType.getNotificationUrgency());
|
||||
notificationType.getNotificationType(), //
|
||||
MainApp.gs(notificationType.getResourceId()), //
|
||||
notificationType.getNotificationUrgency());
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
}
|
||||
|
||||
|
||||
public static void sendNotification(MedtronicNotificationType notificationType, Object... parameters) {
|
||||
Notification notification = new Notification( //
|
||||
notificationType.getNotificationType(), //
|
||||
MainApp.gs(notificationType.getResourceId(), parameters), //
|
||||
notificationType.getNotificationUrgency());
|
||||
notificationType.getNotificationType(), //
|
||||
MainApp.gs(notificationType.getResourceId(), parameters), //
|
||||
notificationType.getNotificationUrgency());
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
}
|
||||
|
||||
|
@ -225,21 +225,21 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
|
||||
|
||||
public static byte[] buildCommandPayload(MedtronicCommandType commandType, byte[] parameters) {
|
||||
return buildCommandPayload((byte)commandType.commandCode, parameters);
|
||||
return buildCommandPayload((byte) commandType.commandCode, parameters);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] buildCommandPayload(byte commandType, byte[] parameters) {
|
||||
// A7 31 65 51 C0 00 52
|
||||
|
||||
byte commandLength = (byte)(parameters == null ? 2 : 2 + parameters.length);
|
||||
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 = RileyLinkUtil.getRileyLinkServiceData().pumpIDBytes;
|
||||
|
||||
sendPayloadBuffer.put((byte)0xA7);
|
||||
sendPayloadBuffer.put((byte) 0xA7);
|
||||
sendPayloadBuffer.put(serialNumberBCD[0]);
|
||||
sendPayloadBuffer.put(serialNumberBCD[1]);
|
||||
sendPayloadBuffer.put(serialNumberBCD[2]);
|
||||
|
@ -247,9 +247,9 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
sendPayloadBuffer.put(commandType);
|
||||
|
||||
if (parameters == null) {
|
||||
sendPayloadBuffer.put((byte)0x00);
|
||||
sendPayloadBuffer.put((byte) 0x00);
|
||||
} else {
|
||||
sendPayloadBuffer.put((byte)parameters.length); // size
|
||||
sendPayloadBuffer.put((byte) parameters.length); // size
|
||||
|
||||
for (byte val : parameters) {
|
||||
sendPayloadBuffer.put(val);
|
||||
|
@ -298,7 +298,7 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
List<Byte> frameData = ByteUtil.getListFromByteArray(substring);
|
||||
|
||||
if (isEmptyFrame(frameData)) {
|
||||
byte b = (byte)frame;
|
||||
byte b = (byte) frame;
|
||||
// b |= 0x80;
|
||||
b |= 0b1000_0000;
|
||||
// b |= doneBit;
|
||||
|
@ -311,7 +311,7 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
|
||||
done = true;
|
||||
} else {
|
||||
frameData.add(0, (byte)frame);
|
||||
frameData.add(0, (byte) frame);
|
||||
}
|
||||
|
||||
// System.out.println("Subarray: " + ByteUtil.getCompactString(substring));
|
||||
|
@ -330,7 +330,7 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
if (!lastFrame) {
|
||||
List<Byte> frameData = new ArrayList<>();
|
||||
|
||||
byte b = (byte)frame;
|
||||
byte b = (byte) frame;
|
||||
b |= 0b1000_0000;
|
||||
// b |= doneBit;
|
||||
|
||||
|
@ -352,7 +352,7 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
int missing = BIG_FRAME_LENGTH - frameData.size();
|
||||
|
||||
for (int i = 0; i < missing; i++) {
|
||||
frameData.add((byte)0x00);
|
||||
frameData.add((byte) 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
|
||||
|
||||
public static MedtronicCommunicationManager getMedtronicCommunicationManager() {
|
||||
return (MedtronicCommunicationManager)RileyLinkUtil.rileyLinkCommunicationManager;
|
||||
return (MedtronicCommunicationManager) RileyLinkUtil.rileyLinkCommunicationManager;
|
||||
}
|
||||
|
||||
|
||||
|
@ -448,6 +448,20 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
|
||||
}
|
||||
|
||||
public static int pageNumber;
|
||||
public static int frameNumber;
|
||||
|
||||
public static void setCurrentCommand(MedtronicCommandType currentCommand, int pageNumber_, int frameNumber_) {
|
||||
pageNumber = pageNumber_;
|
||||
frameNumber = frameNumber_;
|
||||
|
||||
if (MedtronicUtil.currentCommand != currentCommand) {
|
||||
setCurrentCommand(currentCommand);
|
||||
}
|
||||
|
||||
MainApp.bus().post(new EventMedtronicDeviceStatusChange(pumpDeviceState));
|
||||
}
|
||||
|
||||
|
||||
public static boolean isSame(Double d1, Double d2) {
|
||||
double diff = d1 - d2;
|
||||
|
|
|
@ -158,7 +158,7 @@
|
|||
</string-array>
|
||||
|
||||
<string-array name="medtronicPumpFreqArray">
|
||||
<item>@string/medtronic_pump_frequency_us</item>
|
||||
<item>@string/medtronic_pump_frequency_us_ca</item>
|
||||
<item>@string/medtronic_pump_frequency_worldwide</item>
|
||||
</string-array>
|
||||
|
||||
|
|
|
@ -1231,7 +1231,7 @@
|
|||
<string name="medtronic_pump_frequency">Pump Frequency</string>
|
||||
<string name="medtronic_pump_max_bolus">Max Bolus on Pump</string>
|
||||
<string name="medtronic_pump_max_basal">Max Basal on Pump</string>
|
||||
<string name="medtronic_pump_frequency_us">US (916 MHz)</string>
|
||||
<string name="medtronic_pump_frequency_us_ca">US & Canada (916 MHz)</string>
|
||||
<string name="medtronic_pump_frequency_worldwide">Worldwide (868 Mhz)</string>
|
||||
<string name="rileylink_mac_address">RileyLink MAC Address</string>
|
||||
<string name="rileylink_scanner_selected_device">Selected</string>
|
||||
|
@ -1317,8 +1317,12 @@
|
|||
<!-- <string name="medtronic_cmd_profile_not_set">Remote Basal profile setting is not supported. Please modify Basal profile on your pump manually.</string> -->
|
||||
<string name="medtronic_cmd_cancel_bolus_not_supported">Remote cancel of Bolus is not supported. If you wish to cancel bolus, go to pump put it in suspend and then resume. This will cancel the bolus.</string>
|
||||
<string name="medtronic_cmd_cant_read_tbr">Could not read current TBR.</string>
|
||||
<string name="medtronic_cmd_cant_cancel_tbr">Could not cancel current TBR. Stopping operation.</string>
|
||||
<string name="medtronic_cmd_cant_cancel_tbr_stop_op">Could not cancel current TBR. Stopping operation.</string>
|
||||
<string name="medtronic_cmd_set_profile_pattern_overflow">Profile set failed, because following patterns, have too big basal rate: %1$s</string>
|
||||
<string name="medtronic_cmd_bolus_could_not_be_delivered">Bolus could not be delivered.</string>
|
||||
<string name="medtronic_cmd_tbr_could_not_be_delivered">TBR could not be set.</string>
|
||||
<string name="medtronic_cmd_cant_cancel_tbr">Could not cancel current TBR.</string>
|
||||
<string name="medtronic_cmd_basal_profile_could_not_be_set">Basal profile could not be set.</string>
|
||||
|
||||
|
||||
<string name="pump_no_connection_h">No connection for %1$d hour(s) %2$d min</string>
|
||||
|
|
|
@ -0,0 +1,345 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 11/21/18.
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class RFToolsParametrizedUTest {
|
||||
|
||||
private static final String TAG = "RFToolsUTest";
|
||||
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<Object[]> data() {
|
||||
return Arrays
|
||||
.asList(new Object[][] { //
|
||||
{ ByteUtil.createByteArrayFromCompactString("00"), ByteUtil.createByteArrayFromCompactString("5555") },
|
||||
//
|
||||
{
|
||||
ByteUtil.createByteArrayFromCompactString("0000"),
|
||||
ByteUtil.createByteArrayFromCompactString("555555") }, //
|
||||
{
|
||||
ByteUtil.createByteArrayFromCompactString("A71289865D00BE"),
|
||||
ByteUtil.createByteArrayFromCompactString("A96C726996A694D5552CE5") }, //
|
||||
{
|
||||
ByteUtil.createByteArrayFromCompactString("A7128986060015"),
|
||||
ByteUtil.createByteArrayFromCompactString("A96C726996A6566555C655") }, //
|
||||
{
|
||||
ByteUtil.createByteArrayFromCompactString("A7128986150956"),
|
||||
ByteUtil.createByteArrayFromCompactString("A96C726996A6C655599665") }, //
|
||||
{
|
||||
ByteUtil.createByteArrayFromCompactString("A71289868D00B0"),
|
||||
ByteUtil.createByteArrayFromCompactString("A96C726996A668D5552D55") }, //
|
||||
{
|
||||
ByteUtil
|
||||
.createByteArrayFromCompactString("A71289868D090337323200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039"),
|
||||
ByteUtil
|
||||
.createByteArrayFromCompactString("A96C726996A668D5595638D68F28F25555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555558D95")
|
||||
//
|
||||
}, //
|
||||
});
|
||||
}
|
||||
|
||||
@Parameterized.Parameter
|
||||
// first data value (0) is default
|
||||
public/* NOT private */byte[] decoded;
|
||||
|
||||
@Parameterized.Parameter(1)
|
||||
public/* NOT private */byte[] encoded;
|
||||
|
||||
|
||||
// @Test
|
||||
public void testEncodeGeoff() {
|
||||
/*
|
||||
* {0xa7} -> {0xa9, 0x60}
|
||||
* {0xa7, 0x12} -> {0xa9, 0x6c, 0x72}
|
||||
* {0xa7, 0x12, 0xa7} -> {0xa9, 0x6c, 0x72, 0xa9, 0x60}
|
||||
*/
|
||||
/* test compare */
|
||||
// byte[] s1 = { 0, 1, 2 };
|
||||
// byte[] s2 = { 2, 1, 0, 3 };
|
||||
// byte[] s3 = { 0, 1, 2, 3 };
|
||||
// if (ByteUtil.compare(s1, s1) != 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s1, s2) >= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s2, s1) <= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s1, s3) >= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
|
||||
byte[] bs = RFTools.encode4b6b(new byte[] { (byte)0xa7 });
|
||||
byte[] out = new byte[] { (byte)(0xa9), 0x65 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// @Test
|
||||
public void testEncodeGo() {
|
||||
/*
|
||||
* {0xa7} -> {0xa9, 0x60}
|
||||
* {0xa7, 0x12} -> {0xa9, 0x6c, 0x72}
|
||||
* {0xa7, 0x12, 0xa7} -> {0xa9, 0x6c, 0x72, 0xa9, 0x60}
|
||||
*/
|
||||
/* test compare */
|
||||
// byte[] s1 = { 0, 1, 2 };
|
||||
// byte[] s2 = { 2, 1, 0, 3 };
|
||||
// byte[] s3 = { 0, 1, 2, 3 };
|
||||
// if (ByteUtil.compare(s1, s1) != 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s1, s2) >= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s2, s1) <= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s1, s3) >= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
|
||||
byte[] bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7 });
|
||||
byte[] out = new byte[] { (byte)(0xa9), 0x65 };
|
||||
|
||||
System.out.println("EncodeGo: " + ByteUtil.getHex(bs));
|
||||
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7, 0x12 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// @Test
|
||||
public void testDecodeGo() {
|
||||
|
||||
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
|
||||
byte[] bs = RFTools.encode4b6b(new byte[] { (byte)0xa7 });
|
||||
byte[] out = new byte[] { (byte)(0xa9), 0x65 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
}
|
||||
|
||||
byte[] back = RFTools.decode4b6b(out);
|
||||
|
||||
if (ByteUtil.compare(back, bs) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
}
|
||||
|
||||
back = RFTools.decode4b6b(out);
|
||||
|
||||
if (ByteUtil.compare(back, bs) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
}
|
||||
|
||||
back = RFTools.decode4b6b(out);
|
||||
|
||||
if (ByteUtil.compare(back, bs) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// @Test
|
||||
// public void ttt_decodeGo() {
|
||||
//
|
||||
// RFTools.DecodeResponseDto decodeResponseDto = RFTools.decode6b4b_go(new byte[] {
|
||||
// (byte)0xF9, (byte)0xE9, 0x63, (byte)0x9E, 0x7F, (byte)0xE6, 0x79, 0x5F, -1, (byte)0xCF, (byte)0xF0 });
|
||||
//
|
||||
// if (decodeResponseDto.errorData != null) {
|
||||
// Log.e(TAG, decodeResponseDto.errorData);
|
||||
// Assert.assertTrue(false);
|
||||
// } else {
|
||||
// Assert.assertTrue(true);
|
||||
// System.out.println("Response: " + ByteUtil.getHex(decodeResponseDto.data));
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
// @Test
|
||||
public void testParametrizedGeoffEncode() {
|
||||
byte[] encodedX = RFTools.encode4b6b(this.decoded);
|
||||
|
||||
// if (ByteUtil.compare(encodedX, this.encoded) != 0) {
|
||||
// Assert.assertEquals(encodedX, encoded);
|
||||
// }
|
||||
|
||||
Assert.assertArrayEquals(encodedX, encoded);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void geoffDecode() {
|
||||
byte[] decodedX = RFTools.decode4b6b(this.encoded);
|
||||
|
||||
Assert.assertArrayEquals(decoded, decodedX);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void goDecode() {
|
||||
RFTools.DecodeResponseDto decodeResponseDto = RFTools.decode4b6b_go(this.encoded);
|
||||
|
||||
Assert.assertNull(decodeResponseDto.errorData);
|
||||
System.out.println("Result: " + ByteUtil.getHex(decodeResponseDto.data));
|
||||
System.out.println("Expected: " + ByteUtil.getHex(decoded));
|
||||
Assert.assertArrayEquals(decoded, decodeResponseDto.data);
|
||||
}
|
||||
|
||||
|
||||
// @Test
|
||||
public void loopDecode() {
|
||||
byte[] data = RFTools.decode4b6b_loop(this.encoded);
|
||||
|
||||
// RFTools.DecodeResponseDto decodeResponseDto
|
||||
|
||||
// Assert.assertNull(decodeResponseDto.errorData);
|
||||
System.out.println("Result: " + ByteUtil.getHex(data));
|
||||
System.out.println("Expected: " + ByteUtil.getHex(decoded));
|
||||
Assert.assertArrayEquals(decoded, data);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void geoffEncode() {
|
||||
byte[] encodedX = RFTools.encode4b6b(this.decoded);
|
||||
|
||||
Assert.assertArrayEquals(encoded, encodedX);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void goEncode() {
|
||||
byte[] encodedX = RFTools.encode4b6b_go(this.decoded);
|
||||
System.out.println("Result: " + ByteUtil.getHex(encodedX));
|
||||
System.out.println("Expected: " + ByteUtil.getHex(encoded));
|
||||
Assert.assertArrayEquals(encoded, encodedX);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void loopEncode() {
|
||||
byte[] encodedX = RFTools.encode4b6b_loop(this.decoded);
|
||||
System.out.println("Result: " + ByteUtil.getHex(encodedX));
|
||||
System.out.println("Expected: " + ByteUtil.getHex(encoded));
|
||||
Assert.assertArrayEquals(encoded, encodedX);
|
||||
}
|
||||
|
||||
|
||||
private short[] createShortArray(byte[] data) {
|
||||
|
||||
short[] outData = new short[data.length];
|
||||
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
short d = data[i];
|
||||
|
||||
if (d < 0) {
|
||||
d += 256;
|
||||
}
|
||||
|
||||
outData[i] = d;
|
||||
}
|
||||
|
||||
return outData;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 11/21/18.
|
||||
*/
|
||||
|
||||
public class RFToolsUTest {
|
||||
|
||||
private static final String TAG = "RFToolsUTest";
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodeGeoff() {
|
||||
/*
|
||||
* {0xa7} -> {0xa9, 0x60}
|
||||
* {0xa7, 0x12} -> {0xa9, 0x6c, 0x72}
|
||||
* {0xa7, 0x12, 0xa7} -> {0xa9, 0x6c, 0x72, 0xa9, 0x60}
|
||||
*/
|
||||
/* test compare */
|
||||
// byte[] s1 = { 0, 1, 2 };
|
||||
// byte[] s2 = { 2, 1, 0, 3 };
|
||||
// byte[] s3 = { 0, 1, 2, 3 };
|
||||
// if (ByteUtil.compare(s1, s1) != 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s1, s2) >= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s2, s1) <= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s1, s3) >= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
|
||||
byte[] bs = RFTools.encode4b6b(new byte[] { (byte)0xa7 });
|
||||
byte[] out = new byte[] { (byte)(0xa9), 0x65 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodeGo() {
|
||||
/*
|
||||
* {0xa7} -> {0xa9, 0x60}
|
||||
* {0xa7, 0x12} -> {0xa9, 0x6c, 0x72}
|
||||
* {0xa7, 0x12, 0xa7} -> {0xa9, 0x6c, 0x72, 0xa9, 0x60}
|
||||
*/
|
||||
/* test compare */
|
||||
// byte[] s1 = { 0, 1, 2 };
|
||||
// byte[] s2 = { 2, 1, 0, 3 };
|
||||
// byte[] s3 = { 0, 1, 2, 3 };
|
||||
// if (ByteUtil.compare(s1, s1) != 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s1, s2) >= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s2, s1) <= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// if (ByteUtil.compare(s1, s3) >= 0) {
|
||||
// LOG.error("test: compare failed.");
|
||||
// }
|
||||
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
|
||||
byte[] bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7 });
|
||||
byte[] out = new byte[] { (byte)(0xa9), 0x65 };
|
||||
|
||||
System.out.println("EncodeGo: " + ByteUtil.getHex(bs));
|
||||
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7, 0x12 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDecodeGo() {
|
||||
|
||||
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
|
||||
byte[] bs = RFTools.encode4b6b(new byte[] { (byte)0xa7 });
|
||||
byte[] out = new byte[] { (byte)(0xa9), 0x65 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
}
|
||||
|
||||
byte[] back = RFTools.decode4b6b(out);
|
||||
|
||||
if (ByteUtil.compare(back, bs) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
}
|
||||
|
||||
back = RFTools.decode4b6b(out);
|
||||
|
||||
if (ByteUtil.compare(back, bs) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
|
||||
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
|
||||
if (ByteUtil.compare(bs, out) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
}
|
||||
|
||||
back = RFTools.decode4b6b(out);
|
||||
|
||||
if (ByteUtil.compare(back, bs) != 0) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
|
||||
+ ByteUtil.shortHexString(bs));
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void ttt_decodeGo() {
|
||||
|
||||
RFTools.DecodeResponseDto decodeResponseDto = RFTools
|
||||
.decode4b6b_go(new byte[] {
|
||||
(byte)0xF9, (byte)0xE9, 0x63, (byte)0x9E, 0x7F, (byte)0xE6, 0x79, 0x5F, (byte)0xFF, (byte)0xCF,
|
||||
(byte)0xF0 });
|
||||
|
||||
if (decodeResponseDto.errorData != null) {
|
||||
Log.e(TAG, decodeResponseDto.errorData);
|
||||
Assert.assertTrue(false);
|
||||
} else {
|
||||
Assert.assertTrue(true);
|
||||
System.out.println("Response: " + ByteUtil.getHex(decodeResponseDto.data));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void goTest() {
|
||||
System.out.println(RFTools.hi(4, (short)0xa7));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue