From 323f7ae30e0f05a770df3595100a104ffc88ac2f Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Fri, 12 Feb 2021 17:36:58 +0100 Subject: [PATCH] Introduce builder for Omnipod Dash commands --- .../dash/driver/pod/command/CommandBase.java | 47 +++++++++-- .../driver/pod/command/DeactivateCommand.java | 16 ++-- .../driver/pod/command/GetVersionCommand.java | 23 +++--- .../pod/command/ProgramAlertsCommand.java | 26 ++++-- .../pod/command/ProgramBasalCommand.java | 52 ++++++++++++ .../pod/command/SetUniqueIdCommand.java | 44 +++++++++-- .../pod/command/SilenceAlertsCommand.java | 79 +++++++++++++++++-- .../pod/command/StopDeliveryCommand.java | 45 ++++++++++- .../pod/command/interlock/BasalInterlock.java | 4 + .../pod/definition/ProgramReminder.java | 19 +++++ .../program/InsulinProgramElement.java | 26 ++++++ .../pod/command/DeactivateCommandTest.java | 5 +- .../pod/command/GetVersionCommandTest.java | 5 +- .../pod/command/ProgramAlertsCommandTest.java | 30 ++++++- .../pod/command/SetUniqueIdCommandTest.java | 8 +- .../pod/command/SilenceAlertsCommandTest.java | 6 +- .../pod/command/StopDeliveryCommandTest.java | 14 +++- 17 files changed, 396 insertions(+), 53 deletions(-) create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/interlock/BasalInterlock.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ProgramReminder.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/program/InsulinProgramElement.java diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/CommandBase.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/CommandBase.java index e871c07827..637128ceec 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/CommandBase.java +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/CommandBase.java @@ -13,13 +13,13 @@ abstract class CommandBase implements Command { final CommandType commandType; final int address; final short sequenceNumber; - final boolean unknown; + final boolean multiCommandFlag; - CommandBase(CommandType commandType, int address, short sequenceNumber, boolean unknown) { + CommandBase(CommandType commandType, int address, short sequenceNumber, boolean multiCommandFlag) { this.commandType = commandType; this.address = address; this.sequenceNumber = sequenceNumber; - this.unknown = unknown; + this.multiCommandFlag = multiCommandFlag; } @Override public CommandType getCommandType() { @@ -34,8 +34,8 @@ abstract class CommandBase implements Command { return sequenceNumber; } - public boolean isUnknown() { - return unknown; + public boolean isMultiCommandFlag() { + return multiCommandFlag; } static byte[] formatCommand(byte[] command) { @@ -75,10 +75,43 @@ abstract class CommandBase implements Command { .array(); } - static byte[] encodeHeader(int address, short sequenceNumber, short length, boolean unknown) { + static byte[] encodeHeader(int address, short sequenceNumber, short length, boolean multiCommandFlag) { return ByteBuffer.allocate(6) // .putInt(address) // - .putShort((short) (((sequenceNumber & 0x0f) << 10) | length | ((unknown ? 1 : 0) << 15))) // + .putShort((short) (((sequenceNumber & 0x0f) << 10) | length | ((multiCommandFlag ? 1 : 0) << 15))) // .array(); } + + static abstract class Builder, R extends Command> { + Integer address; + Short sequenceNumber; + boolean multiCommandFlag = false; + + public final R build() { + if (address == null) { + throw new IllegalArgumentException("address can not be null"); + } + if (sequenceNumber == null) { + throw new IllegalArgumentException("sequenceNumber can not be null"); + } + return buildCommand(); + } + + public final T setAddress(int address) { + this.address = address; + return (T) this; + } + + public final T setSequenceNumber(short sequenceNumber) { + this.sequenceNumber = sequenceNumber; + return (T) this; + } + + public final T setMultiCommandFlag(boolean multiCommandFlag) { + this.multiCommandFlag = multiCommandFlag; + return (T) this; + } + + abstract R buildCommand(); + } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommand.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommand.java index 57f32dcdb1..813f64c22f 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommand.java +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommand.java @@ -2,17 +2,17 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command; import java.nio.ByteBuffer; -public class DeactivateCommand extends CommandBase { +public final class DeactivateCommand extends CommandBase { private static final short LENGTH = 6; private static final byte BODY_LENGTH = 4; - DeactivateCommand(int address, short sequenceNumber, boolean unknown) { - super(CommandType.DEACTIVATE, address, sequenceNumber, unknown); + private DeactivateCommand(int address, short sequenceNumber, boolean multiCommandFlag) { + super(CommandType.DEACTIVATE, address, sequenceNumber, multiCommandFlag); } @Override public byte[] getEncoded() { return appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // - .put(encodeHeader(address, sequenceNumber, LENGTH, unknown)) // + .put(encodeHeader(address, sequenceNumber, LENGTH, multiCommandFlag)) // .put(commandType.getValue()) // .put(BODY_LENGTH) // .putInt(1229869870) // FIXME ?? was: byte array of int 777211465 converted to little endian @@ -24,7 +24,13 @@ public class DeactivateCommand extends CommandBase { "commandType=" + commandType + ", address=" + address + ", sequenceNumber=" + sequenceNumber + - ", unknown=" + unknown + + ", multiCommandFlag=" + multiCommandFlag + '}'; } + + public static final class Builder extends CommandBase.Builder { + @Override final DeactivateCommand buildCommand() { + return new DeactivateCommand(address, sequenceNumber, multiCommandFlag); + } + } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommand.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommand.java index b1e2296f48..f6426a44a9 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommand.java +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommand.java @@ -2,22 +2,19 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command; import java.nio.ByteBuffer; -public class GetVersionCommand extends CommandBase { - private static final int DEFAULT_ADDRESS = -1; +public final class GetVersionCommand extends CommandBase { + public static final int DEFAULT_ADDRESS = -1; // FIXME move + private static final short LENGTH = 6; private static final byte BODY_LENGTH = 4; - public GetVersionCommand(short sequenceNumber, boolean unknown) { - this(DEFAULT_ADDRESS, sequenceNumber, unknown); - } - - public GetVersionCommand(int address, short sequenceNumber, boolean unknown) { - super(CommandType.GET_VERSION, address, sequenceNumber, unknown); + private GetVersionCommand(int address, short sequenceNumber, boolean multiCommandFlag) { + super(CommandType.GET_VERSION, address, sequenceNumber, multiCommandFlag); } @Override public byte[] getEncoded() { return appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // - .put(encodeHeader(address, sequenceNumber, LENGTH, unknown)) // + .put(encodeHeader(address, sequenceNumber, LENGTH, multiCommandFlag)) // .put(commandType.getValue()) // .put(BODY_LENGTH) // .putInt(address) // @@ -29,7 +26,13 @@ public class GetVersionCommand extends CommandBase { "commandType=" + commandType + ", address=" + address + ", sequenceNumber=" + sequenceNumber + - ", unknown=" + unknown + + ", multiCommandFlag=" + multiCommandFlag + '}'; } + + public static final class Builder extends CommandBase.Builder { + @Override final GetVersionCommand buildCommand() { + return new GetVersionCommand(address, sequenceNumber, multiCommandFlag); + } + } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommand.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommand.java index 8950e8a7e1..ceed5c6a3b 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommand.java +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommand.java @@ -6,17 +6,17 @@ import java.util.List; import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertConfiguration; -public class ProgramAlertsCommand extends CommandBase { +public final class ProgramAlertsCommand extends CommandBase { private final List alertConfigurations; - ProgramAlertsCommand(int address, short sequenceNumber, boolean unknown, List alertConfigurations) { - super(CommandType.PROGRAM_ALERTS, address, sequenceNumber, unknown); + private ProgramAlertsCommand(int address, short sequenceNumber, boolean multiCommandFlag, List alertConfigurations) { + super(CommandType.PROGRAM_ALERTS, address, sequenceNumber, multiCommandFlag); this.alertConfigurations = new ArrayList<>(alertConfigurations); } @Override public byte[] getEncoded() { ByteBuffer byteBuffer = ByteBuffer.allocate(getLength() + HEADER_LENGTH) // - .put(encodeHeader(address, sequenceNumber, getLength(), unknown)) // + .put(encodeHeader(address, sequenceNumber, getLength(), multiCommandFlag)) // .put(commandType.getValue()) // .put(getBodyLength()) // .putInt(1229869870); // FIXME ?? was: byte array of int 777211465 converted to little endian @@ -40,7 +40,23 @@ public class ProgramAlertsCommand extends CommandBase { ", commandType=" + commandType + ", address=" + address + ", sequenceNumber=" + sequenceNumber + - ", unknown=" + unknown + + ", multiCommandFlag=" + multiCommandFlag + '}'; } + + public static final class Builder extends CommandBase.Builder { + private List alertConfigurations; + + public Builder setAlertConfigurations(List alertConfigurations) { + this.alertConfigurations = alertConfigurations; + return this; + } + + @Override final ProgramAlertsCommand buildCommand() { + if (this.alertConfigurations == null) { + throw new IllegalArgumentException("alertConfigurations can not be null"); + } + return new ProgramAlertsCommand(address, sequenceNumber, multiCommandFlag, alertConfigurations); + } + } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.java new file mode 100644 index 0000000000..ea9863ae75 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.java @@ -0,0 +1,52 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command; + +import java.util.ArrayList; +import java.util.List; + +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ProgramReminder; +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.program.InsulinProgramElement; + +public final class ProgramBasalCommand extends CommandBase { + private final List insulinProgramElements; + + private ProgramBasalCommand(int address, short sequenceNumber, boolean multiCommandFlag, ProgramReminder programReminder, List insulinProgramElements) { + super(CommandType.PROGRAM_BASAL, address, sequenceNumber, multiCommandFlag); + this.insulinProgramElements = new ArrayList<>(insulinProgramElements); + this.programReminder = programReminder; + } + + private final ProgramReminder programReminder; + + @Override public byte[] getEncoded() { + return new byte[0]; + } + + public static final class Builder extends CommandBase.Builder { + private List insulinProgramElements; + private ProgramReminder programReminder; + + public Builder setInsulinProgramElements(List insulinProgramElements) { + if (insulinProgramElements == null) { + throw new IllegalArgumentException("insulinProgramElements can not be null"); + } + this.insulinProgramElements = new ArrayList<>(insulinProgramElements); + return this; + } + + public Builder setProgramReminder(ProgramReminder programReminder) { + this.programReminder = programReminder; + return this; + } + + @Override final ProgramBasalCommand buildCommand() { + if (insulinProgramElements == null) { + throw new IllegalArgumentException("insulinProgramElements can not be null"); + } + if (programReminder == null) { + throw new IllegalArgumentException("programReminder can not be null"); + } + return new ProgramBasalCommand(address, sequenceNumber, multiCommandFlag, programReminder, insulinProgramElements); + } + } + +} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommand.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommand.java index c4849e1fd6..fae43f9119 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommand.java +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommand.java @@ -4,7 +4,7 @@ import java.nio.ByteBuffer; import java.util.Calendar; import java.util.Date; -public class SetUniqueIdCommand extends CommandBase { +public final class SetUniqueIdCommand extends CommandBase { private static final int DEFAULT_ADDRESS = -1; private static final short LENGTH = 21; private static final byte BODY_LENGTH = 19; @@ -13,8 +13,8 @@ public class SetUniqueIdCommand extends CommandBase { private final int podSequenceNumber; private final Date initializationTime; - SetUniqueIdCommand(int address, short sequenceNumber, int lotNumber, int podSequenceNumber, Date initializationTime, boolean unknown) { - super(CommandType.SET_UNIQUE_ID, address, sequenceNumber, unknown); + private SetUniqueIdCommand(int address, short sequenceNumber, boolean multiCommandFlag, int lotNumber, int podSequenceNumber, Date initializationTime) { + super(CommandType.SET_UNIQUE_ID, address, sequenceNumber, multiCommandFlag); this.lotNumber = lotNumber; this.podSequenceNumber = podSequenceNumber; this.initializationTime = initializationTime; @@ -22,7 +22,7 @@ public class SetUniqueIdCommand extends CommandBase { @Override public byte[] getEncoded() { return appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // - .put(encodeHeader(DEFAULT_ADDRESS, sequenceNumber, LENGTH, unknown)) // + .put(encodeHeader(DEFAULT_ADDRESS, sequenceNumber, LENGTH, multiCommandFlag)) // .put(commandType.getValue()) // .put(BODY_LENGTH) // .putInt(address) // @@ -55,7 +55,41 @@ public class SetUniqueIdCommand extends CommandBase { ", commandType=" + commandType + ", address=" + address + ", sequenceNumber=" + sequenceNumber + - ", unknown=" + unknown + + ", multiCommandFlag=" + multiCommandFlag + '}'; } + + public static final class Builder extends CommandBase.Builder { + private Integer lotNumber; + private Integer podSequenceNumber; + private Date initializationTime; + + public Builder setLotNumber(int lotNumber) { + this.lotNumber = lotNumber; + return this; + } + + public Builder setPodSequenceNumber(int podSequenceNumber) { + this.podSequenceNumber = podSequenceNumber; + return this; + } + + public Builder setInitializationTime(Date initializationTime) { + this.initializationTime = initializationTime; + return this; + } + + @Override final SetUniqueIdCommand buildCommand() { + if (lotNumber == null) { + throw new IllegalArgumentException("lotNumber can not be null"); + } + if (podSequenceNumber == null) { + throw new IllegalArgumentException("podSequenceNumber can not be null"); + } + if (initializationTime == null) { + throw new IllegalArgumentException("initializationTime can not be null"); + } + return new SetUniqueIdCommand(address, sequenceNumber, multiCommandFlag, lotNumber, podSequenceNumber, initializationTime); + } + } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommand.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommand.java index bb2609846f..dd8f03fc97 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommand.java +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommand.java @@ -3,20 +3,20 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command; import java.nio.ByteBuffer; import java.util.BitSet; -public class SilenceAlertsCommand extends CommandBase { +public final class SilenceAlertsCommand extends CommandBase { private static final short LENGTH = (short) 7; private static final byte BODY_LENGTH = (byte) 5; private final SilenceAlertCommandParameters parameters; - public SilenceAlertsCommand(int address, short sequenceNumber, boolean unknown, SilenceAlertCommandParameters parameters) { - super(CommandType.SILENCE_ALERTS, address, sequenceNumber, unknown); + private SilenceAlertsCommand(int address, short sequenceNumber, boolean multiCommandFlag, SilenceAlertCommandParameters parameters) { + super(CommandType.SILENCE_ALERTS, address, sequenceNumber, multiCommandFlag); this.parameters = parameters; } @Override public byte[] getEncoded() { return appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // - .put(encodeHeader(address, sequenceNumber, LENGTH, unknown)) // + .put(encodeHeader(address, sequenceNumber, LENGTH, multiCommandFlag)) // .put(commandType.getValue()) // .put(BODY_LENGTH) // .putInt(1229869870) // FIXME ?? was: byte array of int 777211465 converted to little endian @@ -24,7 +24,17 @@ public class SilenceAlertsCommand extends CommandBase { .array()); } - public static final class SilenceAlertCommandParameters { + @Override public String toString() { + return "SilenceAlertsCommand{" + + "parameters=" + parameters + + ", commandType=" + commandType + + ", address=" + address + + ", sequenceNumber=" + sequenceNumber + + ", multiCommandFlag=" + multiCommandFlag + + '}'; + } + + private static final class SilenceAlertCommandParameters { private final boolean silenceAutoOffAlert; private final boolean silenceMultiCommandAlert; private final boolean silenceExpirationImminentAlert; @@ -34,7 +44,7 @@ public class SilenceAlertsCommand extends CommandBase { private final boolean silenceSuspendEndedAlert; private final boolean silencePodExpirationAlert; - public SilenceAlertCommandParameters(boolean silenceAutoOffAlert, boolean silenceMultiCommandAlert, boolean silenceExpirationImminentAlert, boolean silenceUserSetExpirationAlert, boolean silenceLowReservoirAlert, boolean silenceSuspendInProgressAlert, boolean silenceSuspendEndedAlert, boolean silencePodExpirationAlert) { + private SilenceAlertCommandParameters(boolean silenceAutoOffAlert, boolean silenceMultiCommandAlert, boolean silenceExpirationImminentAlert, boolean silenceUserSetExpirationAlert, boolean silenceLowReservoirAlert, boolean silenceSuspendInProgressAlert, boolean silenceSuspendEndedAlert, boolean silencePodExpirationAlert) { this.silenceAutoOffAlert = silenceAutoOffAlert; this.silenceMultiCommandAlert = silenceMultiCommandAlert; this.silenceExpirationImminentAlert = silenceExpirationImminentAlert; @@ -45,7 +55,7 @@ public class SilenceAlertsCommand extends CommandBase { this.silencePodExpirationAlert = silencePodExpirationAlert; } - public byte[] getEncoded() { + private byte[] getEncoded() { BitSet bitSet = new BitSet(8); bitSet.set(0, this.silenceAutoOffAlert); bitSet.set(1, this.silenceMultiCommandAlert); @@ -58,4 +68,59 @@ public class SilenceAlertsCommand extends CommandBase { return bitSet.toByteArray(); } } + + public static class Builder extends CommandBase.Builder { + private boolean silenceAutoOffAlert; + private boolean silenceMultiCommandAlert; + private boolean silenceExpirationImminentAlert; + private boolean silenceUserSetExpirationAlert; + private boolean silenceLowReservoirAlert; + private boolean silenceSuspendInProgressAlert; + private boolean silenceSuspendEndedAlert; + private boolean silencePodExpirationAlert; + + public Builder setSilenceAutoOffAlert(boolean silenceAutoOffAlert) { + this.silenceAutoOffAlert = silenceAutoOffAlert; + return this; + } + + public Builder setSilenceMultiCommandAlert(boolean silenceMultiCommandAlert) { + this.silenceMultiCommandAlert = silenceMultiCommandAlert; + return this; + } + + public Builder setSilenceExpirationImminentAlert(boolean silenceExpirationImminentAlert) { + this.silenceExpirationImminentAlert = silenceExpirationImminentAlert; + return this; + } + + public Builder setSilenceUserSetExpirationAlert(boolean silenceUserSetExpirationAlert) { + this.silenceUserSetExpirationAlert = silenceUserSetExpirationAlert; + return this; + } + + public Builder setSilenceLowReservoirAlert(boolean silenceLowReservoirAlert) { + this.silenceLowReservoirAlert = silenceLowReservoirAlert; + return this; + } + + public Builder setSilenceSuspendInProgressAlert(boolean silenceSuspendInProgressAlert) { + this.silenceSuspendInProgressAlert = silenceSuspendInProgressAlert; + return this; + } + + public Builder setSilenceSuspendEndedAlert(boolean silenceSuspendEndedAlert) { + this.silenceSuspendEndedAlert = silenceSuspendEndedAlert; + return this; + } + + public Builder setSilencePodExpirationAlert(boolean silencePodExpirationAlert) { + this.silencePodExpirationAlert = silencePodExpirationAlert; + return this; + } + + @Override SilenceAlertsCommand buildCommand() { + return new SilenceAlertsCommand(address, sequenceNumber, multiCommandFlag, new SilenceAlertCommandParameters(silenceAutoOffAlert, silenceMultiCommandAlert, silenceExpirationImminentAlert, silenceUserSetExpirationAlert, silenceLowReservoirAlert, silenceSuspendInProgressAlert, silenceSuspendEndedAlert, silencePodExpirationAlert)); + } + } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommand.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommand.java index 99cc1da256..b6aa2b97b8 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommand.java +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommand.java @@ -5,22 +5,22 @@ import java.util.BitSet; import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType; -public class StopDeliveryCommand extends CommandBase { +public final class StopDeliveryCommand extends CommandBase { private static final short LENGTH = 7; private static final byte BODY_LENGTH = 5; private final DeliveryType deliveryType; private final BeepType beepType; - public StopDeliveryCommand(int address, short sequenceNumber, boolean unknown, DeliveryType deliveryType, BeepType beepType) { - super(CommandType.STOP_DELIVERY, address, sequenceNumber, unknown); + private StopDeliveryCommand(int address, short sequenceNumber, boolean multiCommandFlag, DeliveryType deliveryType, BeepType beepType) { + super(CommandType.STOP_DELIVERY, address, sequenceNumber, multiCommandFlag); this.deliveryType = deliveryType; this.beepType = beepType; } @Override public byte[] getEncoded() { return appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // - .put(encodeHeader(address, sequenceNumber, LENGTH, unknown)) // + .put(encodeHeader(address, sequenceNumber, LENGTH, multiCommandFlag)) // .put(commandType.getValue()) // .put(BODY_LENGTH) // .putInt(1229869870) // FIXME ?? was: byte array of int 777211465 converted to little endian @@ -28,6 +28,17 @@ public class StopDeliveryCommand extends CommandBase { .array()); } + @Override public String toString() { + return "StopDeliveryCommand{" + + "deliveryType=" + deliveryType + + ", beepType=" + beepType + + ", commandType=" + commandType + + ", address=" + address + + ", sequenceNumber=" + sequenceNumber + + ", multiCommandFlag=" + multiCommandFlag + + '}'; + } + public enum DeliveryType { BASAL(true, false, false), TEMP_BASAL(false, true, false), @@ -52,4 +63,30 @@ public class StopDeliveryCommand extends CommandBase { return bitSet.toByteArray()[0]; } } + + public static final class Builder extends CommandBase.Builder { + private DeliveryType deliveryType; + private BeepType beepType = BeepType.LONG_SINGLE_BEEP; + + public Builder setDeliveryType(DeliveryType deliveryType) { + this.deliveryType = deliveryType; + return this; + } + + public Builder setBeepType(BeepType beepType) { + this.beepType = beepType; + return this; + } + + @Override final StopDeliveryCommand buildCommand() { + if (this.deliveryType == null) { + throw new IllegalArgumentException("deliveryType can not be null"); + } + if (this.deliveryType == null) { + throw new IllegalArgumentException("beepType can not be null"); + } + return new StopDeliveryCommand(address, sequenceNumber, multiCommandFlag, deliveryType, beepType); + } + } + } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/interlock/BasalInterlock.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/interlock/BasalInterlock.java new file mode 100644 index 0000000000..32c5c00fd6 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/interlock/BasalInterlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.interlock; + +public class BasalInterlock { +} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ProgramReminder.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ProgramReminder.java new file mode 100644 index 0000000000..8daf6fa609 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/ProgramReminder.java @@ -0,0 +1,19 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition; + +public class ProgramReminder { + private final boolean atStart; + private final boolean atEnd; + private final byte atInterval; + + public ProgramReminder(boolean atStart, boolean atEnd, byte atIntervalInMinutes) { + this.atStart = atStart; + this.atEnd = atEnd; + this.atInterval = atIntervalInMinutes; + } + + public byte getEncoded() { + return (byte) (((this.atStart ? 0 : 1) << 7) + | ((this.atEnd ? 0 : 1) << 6) + | (this.atInterval & 0x3f)); + } +} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/program/InsulinProgramElement.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/program/InsulinProgramElement.java new file mode 100644 index 0000000000..2ffea46ec1 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/program/InsulinProgramElement.java @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.program; + +import java.nio.ByteBuffer; + +public class InsulinProgramElement { + private final byte numberOfHalfOurEntries; // 4 bits + private final short numberOfPulsesPerHalfOurEntry; // 10 bits + private final boolean extraAlternatePulse; + + public InsulinProgramElement(byte numberOfHalfOurEntries, short numberOfPulsesPerHalfOurEntry, boolean extraAlternatePulse) { + this.numberOfHalfOurEntries = numberOfHalfOurEntries; + this.numberOfPulsesPerHalfOurEntry = numberOfPulsesPerHalfOurEntry; + this.extraAlternatePulse = extraAlternatePulse; + } + + public byte[] getEncoded() { + byte firstByte = (byte) ((((numberOfHalfOurEntries - 1) & 0x0f) << 4) + | ((extraAlternatePulse ? 1 : 0) << 3) + | ((numberOfPulsesPerHalfOurEntry >>> 8) & 0x03)); + + return ByteBuffer.allocate(2) // + .put(firstByte) + .put((byte) (numberOfPulsesPerHalfOurEntry & 0xff)) // + .array(); + } +} diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommandTest.java b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommandTest.java index b0b4b5380b..a84b03cf58 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommandTest.java +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/DeactivateCommandTest.java @@ -9,7 +9,10 @@ import static org.junit.Assert.assertArrayEquals; public class DeactivateCommandTest { @Test public void testEncoding() throws DecoderException { - byte[] encoded = new DeactivateCommand(37879809, (short) 5, false) // + byte[] encoded = new DeactivateCommand.Builder() // + .setAddress(37879809) // + .setSequenceNumber((short) 5) // + .build() // .getEncoded(); assertArrayEquals(Hex.decodeHex("0242000114061C04494E532E001C"), encoded); diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommandTest.java b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommandTest.java index 5750932ffa..46a31bca97 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommandTest.java +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/GetVersionCommandTest.java @@ -9,7 +9,10 @@ import static org.junit.Assert.assertArrayEquals; public class GetVersionCommandTest { @Test public void testEncoding() throws DecoderException { - byte[] encoded = new GetVersionCommand((short) 0, false) // + byte[] encoded = new GetVersionCommand.Builder() // + .setSequenceNumber((short) 0) // + .setAddress(GetVersionCommand.DEFAULT_ADDRESS) // + .build() // .getEncoded(); assertArrayEquals(Hex.decodeHex("FFFFFFFF00060704FFFFFFFF82B2"), encoded); diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommandTest.java b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommandTest.java index f054efc0eb..9b2ba193fe 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommandTest.java +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramAlertsCommandTest.java @@ -22,7 +22,13 @@ public class ProgramAlertsCommandTest { configurations.add(new AlertConfiguration(AlertSlot.EXPIRATION, true, (short) 420, false, AlertTriggerType.TIME_TRIGGER, (short) 4305, BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX3)); configurations.add(new AlertConfiguration(AlertSlot.EXPIRATION_IMMINENT, true, (short) 0, false, AlertTriggerType.TIME_TRIGGER, (short) 4725, BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX4)); - byte[] encoded = new ProgramAlertsCommand(37879811, (short) 3, true, configurations).getEncoded(); + byte[] encoded = new ProgramAlertsCommand.Builder() // + .setAddress(37879811) // + .setSequenceNumber((short) 3) // + .setMultiCommandFlag(true) // + .setAlertConfigurations(configurations) // + .build() // + .getEncoded(); assertArrayEquals(Hex.decodeHex("024200038C121910494E532E79A410D1050228001275060280F5"), encoded); } @@ -32,7 +38,12 @@ public class ProgramAlertsCommandTest { List configurations = new ArrayList<>(); configurations.add(new AlertConfiguration(AlertSlot.LOW_RESERVOIR, true, (short) 0, false, AlertTriggerType.RESERVOIR_VOLUME_TRIGGER, (short) 200, BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX)); - byte[] encoded = new ProgramAlertsCommand(37879811, (short) 8, false, configurations).getEncoded(); + byte[] encoded = new ProgramAlertsCommand.Builder() // + .setAddress(37879811) // + .setSequenceNumber((short) 8) // + .setAlertConfigurations(configurations) // + .build() // + .getEncoded(); assertArrayEquals(Hex.decodeHex("02420003200C190A494E532E4C0000C801020149"), encoded); } @@ -42,7 +53,12 @@ public class ProgramAlertsCommandTest { List configurations = new ArrayList<>(); configurations.add(new AlertConfiguration(AlertSlot.USER_SET_EXPIRATION, true, (short) 0, false, AlertTriggerType.TIME_TRIGGER, (short) 4079, BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX2)); - byte[] encoded = new ProgramAlertsCommand(37879811, (short) 15, false, configurations).getEncoded(); + byte[] encoded = new ProgramAlertsCommand.Builder() // + .setAddress(37879811) // + .setSequenceNumber((short) 15) // + .setAlertConfigurations(configurations) // + .build() // + .getEncoded(); assertArrayEquals(Hex.decodeHex("024200033C0C190A494E532E38000FEF030203E2"), encoded); } @@ -53,7 +69,13 @@ public class ProgramAlertsCommandTest { List configurations = new ArrayList<>(); configurations.add(new AlertConfiguration(AlertSlot.EXPIRATION, true, (short) 55, false, AlertTriggerType.TIME_TRIGGER, (short) 5, BeepType.FOUR_TIMES_BIP_BEEP, BeepRepetitionType.XXX5)); - byte[] encoded = new ProgramAlertsCommand(37879811, (short) 10, false, configurations).getEncoded(); + byte[] encoded = new ProgramAlertsCommand.Builder() // + .setAddress(37879811) // + .setSequenceNumber((short) 10) // + .setMultiCommandFlag(false) // + .setAlertConfigurations(configurations) // + .build() // + .getEncoded(); assertArrayEquals(Hex.decodeHex("02420003280C190A494E532E7837000508020356"), encoded); } diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommandTest.java b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommandTest.java index 055f215e5d..7c6c4c1895 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommandTest.java +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SetUniqueIdCommandTest.java @@ -11,7 +11,13 @@ import static org.junit.Assert.assertArrayEquals; public class SetUniqueIdCommandTest { @Test public void testEncoding() throws DecoderException { - byte[] encoded = new SetUniqueIdCommand(37879811, (short) 6, 135556289, 681767, new Date(2021, 1, 10, 14, 41), false) // + byte[] encoded = new SetUniqueIdCommand.Builder() // + .setAddress(37879811) // + .setSequenceNumber((short) 6) + .setLotNumber(135556289) // + .setPodSequenceNumber(681767) // + .setInitializationTime(new Date(2021, 1, 10, 14, 41)) // + .build() // .getEncoded(); assertArrayEquals(Hex.decodeHex("FFFFFFFF18150313024200031404020A150E2908146CC1000A67278344"), encoded); diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommandTest.java b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommandTest.java index 57d9ad20fb..0be759b03a 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommandTest.java +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/SilenceAlertsCommandTest.java @@ -9,7 +9,11 @@ import static org.junit.Assert.assertArrayEquals; public class SilenceAlertsCommandTest { @Test public void testSilenceLowReservoirAlert() throws DecoderException { - byte[] encoded = new SilenceAlertsCommand(37879811, (short) 1, false, new SilenceAlertsCommand.SilenceAlertCommandParameters(false, false, false, false, true, false, false, false)) // + byte[] encoded = new SilenceAlertsCommand.Builder() // + .setAddress(37879811) // + .setSequenceNumber((short) 1) + .setSilenceLowReservoirAlert(true) // + .build() // .getEncoded(); assertArrayEquals(Hex.decodeHex("0242000304071105494E532E1081CE"), encoded); diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommandTest.java b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommandTest.java index 35fa7e63a3..4277ba3711 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommandTest.java +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/StopDeliveryCommandTest.java @@ -11,7 +11,12 @@ import static org.junit.Assert.assertArrayEquals; public class StopDeliveryCommandTest { @Test public void testStopTempBasal() throws DecoderException { - byte[] encoded = new StopDeliveryCommand(37879811, (short) 0, false, StopDeliveryCommand.DeliveryType.TEMP_BASAL, BeepType.LONG_SINGLE_BEEP) // + byte[] encoded = new StopDeliveryCommand.Builder() // + .setAddress(37879811) // + .setSequenceNumber((short) 0) // + .setDeliveryType(StopDeliveryCommand.DeliveryType.TEMP_BASAL) // + .setBeepType(BeepType.LONG_SINGLE_BEEP) // + .build() // .getEncoded(); assertArrayEquals(Hex.decodeHex("0242000300071F05494E532E6201B1"), encoded); @@ -19,7 +24,12 @@ public class StopDeliveryCommandTest { @Test public void testSuspendDelivery() throws DecoderException { - byte[] encoded = new StopDeliveryCommand(37879811, (short) 2, false, StopDeliveryCommand.DeliveryType.ALL, BeepType.SILENT) // + byte[] encoded = new StopDeliveryCommand.Builder() // + .setAddress(37879811) // + .setSequenceNumber((short) 2) // + .setDeliveryType(StopDeliveryCommand.DeliveryType.ALL) // + .setBeepType(BeepType.SILENT) // + .build() // .getEncoded(); assertArrayEquals(Hex.decodeHex("0242000308071F05494E532E078287"), encoded);