SPI first draft.

This commit is contained in:
Johannes Mockenhaupt 2017-10-18 12:57:46 +02:00
parent 4a91b68ed7
commit e5eba342ba
No known key found for this signature in database
GPG key ID: 9E1EA6AF7BBBB0D1
24 changed files with 311 additions and 54 deletions

View file

@ -126,11 +126,14 @@ public class ComboFragment extends Fragment implements View.OnClickListener {
tbrRateText.setText("");
}
pumpErrorText.setText(ps.errorMsg != null ? ps.errorMsg : "");
if(ps.lowBattery){
if(ps.batteryState == PumpState.EMPTY){
pumpstateBatteryText.setText("{fa-battery-empty}");
pumpstateBatteryText.setTextColor(Color.RED);
} else if(ps.batteryState == PumpState.LOW){
pumpstateBatteryText.setText("{fa-battery-quarter}");
pumpstateBatteryText.setTextColor(Color.WHITE);
} else {
pumpstateBatteryText.setText("{fa-battery-three-quarters}");
pumpstateBatteryText.setText("{fa-battery-full}");
pumpstateBatteryText.setTextColor(Color.WHITE);
}
switch (ps.insulinState){

View file

@ -29,7 +29,7 @@ import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.plugins.PumpCombo.events.EventComboPumpUpdateGUI;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.RuffyCommandsV1Impl;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.BolusProgressReporter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.CommandResult;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.PumpState;
@ -73,7 +73,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
definePumpCapabilities();
MainApp.bus().register(this);
startAlerter();
ruffyScripter = new RuffyScripter();
ruffyScripter = RuffyCommandsV1Impl.getInstance();
}
private void definePumpCapabilities() {

View file

@ -0,0 +1,73 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy;
import java.util.Date;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.BasalProfile;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.BolusProgressReporter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.CommandResult;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.PumpHistory;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.RuffyCommands;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.PumpHistoryRequest;
public class RuffyCommandsV1Impl implements RuffyCommands {
private static RuffyCommands delegate;
public static RuffyCommands getInstance() {
if (delegate == null) delegate = new RuffyScripter();
return delegate;
}
private RuffyCommandsV1Impl() {
}
@Override
public CommandResult deliverBolus(double amount, BolusProgressReporter bolusProgressReporter) {
return delegate.deliverBolus(amount, bolusProgressReporter);
}
@Override
public void cancelBolus() {
delegate.cancelBolus();
}
@Override
public CommandResult setTbr(int percent, int duration) {
return delegate.setTbr(percent, duration);
}
@Override
public CommandResult cancelTbr() {
return delegate.cancelTbr();
}
@Override
public boolean isPumpAvailable() {
return delegate.isPumpAvailable();
}
@Override
public boolean isPumpBusy() {
return delegate.isPumpBusy();
}
@Override
public CommandResult readHistory(PumpHistoryRequest request) {
return delegate.readHistory(request);
}
@Override
public CommandResult readBasalProfile(int number) {
return delegate.readBasalProfile(number);
}
@Override
public CommandResult setBasalProfile(BasalProfile basalProfile) {
return delegate.setBasalProfile(basalProfile);
}
@Override
public CommandResult setDateAndTime(Date date) {
return delegate.setDateAndTime(date);
}
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy;
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter;
import android.content.ComponentName;
import android.content.Context;
@ -20,6 +20,7 @@ import org.monkey.d.ruffy.ruffy.driver.display.menu.MenuTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@ -37,9 +38,13 @@ import info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.comm
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.BasalProfile;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.BolusProgressReporter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.CommandResult;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.PumpHistory;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.Bolus;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.PumpHistory;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.PumpState;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.RuffyCommands;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.PumpHistoryRequest;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.Tbr;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.Tdd;
// TODO regularly read "My data" history (boluses, TBR) to double check all commands ran successfully.
// Automatically compare against AAPS db, or log all requests in the PumpInterface (maybe Milos
@ -452,7 +457,8 @@ public class RuffyScripter implements RuffyCommands {
state.tbrRemainingDuration = durationMenuTime.getHour() * 60 + durationMenuTime.getMinute();
state.tbrRate = ((double) menu.getAttribute(MenuAttribute.BASAL_RATE));
}
state.lowBattery = ((boolean) menu.getAttribute(MenuAttribute.LOW_BATTERY));
// ruffy doesn't support 'empty battery' flag, not sure if the pump does
state.batteryState = ((boolean) menu.getAttribute(MenuAttribute.LOW_BATTERY)) ? PumpState.LOW : -1;
state.insulinState = ((int) menu.getAttribute(MenuAttribute.INSULIN_STATE));
// TODO v2, read current base basal rate, which is shown center when no TBR is active.
// Check if that holds true when an extended bolus is running.
@ -462,7 +468,8 @@ public class RuffyScripter implements RuffyCommands {
state.errorMsg = (String) menu.getAttribute(MenuAttribute.MESSAGE);
} else if (menuType == MenuType.STOP) {
state.suspended = true;
state.lowBattery = ((boolean) menu.getAttribute(MenuAttribute.LOW_BATTERY));
// ruffy doesn't support 'empty battery' flag, not sure if the pump does
state.batteryState = ((boolean) menu.getAttribute(MenuAttribute.LOW_BATTERY)) ? PumpState.LOW : -1;
state.insulinState = ((int) menu.getAttribute(MenuAttribute.INSULIN_STATE));
} else {
StringBuilder sb = new StringBuilder();
@ -750,8 +757,8 @@ public class RuffyScripter implements RuffyCommands {
}
@Override
public CommandResult setTbr(int percent, int duraton) {
return runCommand(new SetTbrCommand(percent, duraton));
public CommandResult setTbr(int percent, int duration) {
return runCommand(new SetTbrCommand(percent, duration));
}
@Override
@ -760,18 +767,18 @@ public class RuffyScripter implements RuffyCommands {
}
@Override
public CommandResult readReservoirLevel() {
return runCommand(new ReadReserverLevelCommand());
public CommandResult readHistory(PumpHistoryRequest request) {
return new CommandResult().history(
new PumpHistory(50,
Collections.<Bolus>emptyList(),
Collections.<Tbr>emptyList(),
Collections.<Error>emptyList(),
Collections.<Tdd>emptyList()));
}
@Override
public CommandResult readHistory(PumpHistory knownHistory) {
return runCommand(new ReadHistoryCommand(knownHistory));
}
@Override
public CommandResult readBasalProfile() {
return runCommand(new ReadBasalProfileCommand());
public CommandResult readBasalProfile(int number) {
return runCommand(new ReadBasalProfileCommand(number));
}
@Override

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.commands;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.RuffyScripter;
public abstract class BaseCommand implements Command {
// RS will inject itself here

View file

@ -11,7 +11,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.BolusProgressReporter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.CommandResult;

View file

@ -2,7 +2,7 @@ package info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.com
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.CommandResult;
/**

View file

@ -10,7 +10,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.CommandResult;
public class GetBasalRateProfileCommand extends BaseCommand {

View file

@ -2,10 +2,16 @@ package info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.com
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.CommandResult;
public class ReadBasalProfileCommand implements Command {
private final int number;
public ReadBasalProfileCommand(int number) {
this.number = number;
}
@Override
public CommandResult execute() {
return null;

View file

@ -2,8 +2,8 @@ package info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.com
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.PumpHistory;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.PumpHistory;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.CommandResult;
public class ReadHistoryCommand implements Command {

View file

@ -2,7 +2,7 @@ package info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.com
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.CommandResult;
public class ReadReserverLevelCommand implements Command {

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.com
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.BasalProfile;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.internal.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.CommandResult;
public class SetBasalProfileCommand implements Command {

View file

@ -1,4 +1,13 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi;
public class BasalProfile {
public final int number;
public final double[] hourlyRates;
public BasalProfile(int number, double[] hourlyRates) {
this.number = number;
if (hourlyRates.length != 24)
throw new IllegalArgumentException("Profile must have 24 hourly rates");
this.hourlyRates = hourlyRates;
}
}

View file

@ -1,16 +1,30 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi;
import java.util.Date;
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.PumpHistory;
public class CommandResult {
/** The request made made to the pump, like setting a TBR. */
public String request;
/** Whether the command was executed successfully. */
public boolean success;
/** Whether any changes were made, e.g. if a the request was to cancel a running TBR,
* but not TBR was active, this will be false. */
public boolean enacted;
/** Time the command completed. */
public long completionTime;
/** Null unless an unhandled exception was raised. */
public Exception exception;
/** (Error)message describing the result of the command. */
public String message;
/** State of the pump *after* command execution. */
public PumpState state;
/** History if requested by the command. */
public PumpHistory history;
/** Basal rate profile if requested. */
public List<BasalProfile> basalProfiles;
/** Total duration the command took. */
public String duration;
public CommandResult() {
@ -61,17 +75,24 @@ public class CommandResult {
return this;
}
public CommandResult basalProfile(List<BasalProfile> basalProfiles) {
this.basalProfiles = basalProfiles;
return this;
}
@Override
public String toString() {
return "CommandResult{" +
"request=" + request +
"request='" + request + '\'' +
", success=" + success +
", enacted=" + enacted +
", completionTime=" + completionTime + "(" + new Date(completionTime) + ")" +
"' duration=" + duration +
", completionTime=" + completionTime +
", exception=" + exception +
", message='" + message + '\'' +
", state=" + state +
", history=" + history +
", basalProfiles=" + basalProfiles +
", duration='" + duration + '\'' +
'}';
}
}

View file

@ -1,4 +0,0 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi;
public class PumpHistory {
}

View file

@ -3,13 +3,17 @@ package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi;
import java.util.Date;
/**
* State representing the state of the MAIN_MENU.
* State representing the state of the MAIN_MENU, plus reservoir level (if requested).
*/
public class PumpState {
public Date timestamp = new Date();
public boolean tbrActive = false;
/** TBR percentage. 100% means no TBR active, just the normal basal rate running. */
public int tbrPercent = -1;
/** The absolute rate the TBR is running, e.g. 0.80U/h. */
public double tbrRate = -1;
/** Remaining time of an active TBR. Note that 0:01 is te lowest displayed, the pump
* jumps from that to TBR end, skipping 0:00(xx). */
public int tbrRemainingDuration = -1;
/**
* This is the error message (if any) displayed by the pump if there is an alarm,
@ -20,9 +24,14 @@ public class PumpState {
*/
public String errorMsg;
public boolean suspended;
public boolean lowBattery;
public static final int LOW = 1;
public static final int EMPTY = 2;
public int batteryState = - 1;
public int insulinState = -1;
public int reservoirLevel = -1;
public int activeBasalProfileNumber;
public PumpState tbrActive(boolean tbrActive) {
this.tbrActive = tbrActive;
@ -54,8 +63,8 @@ public class PumpState {
return this;
}
public PumpState lowBattery(boolean lowBattery) {
this.lowBattery = lowBattery;
public PumpState batteryState(int batteryState) {
this.batteryState = batteryState;
return this;
}
@ -64,8 +73,8 @@ public class PumpState {
return this;
}
public PumpState reservoirLevel(int reservoirLevel) {
this.reservoirLevel = reservoirLevel;
public PumpState activeBasalProfileNumber(int activeBasalProfileNumber) {
this.activeBasalProfileNumber = activeBasalProfileNumber;
return this;
}
@ -80,16 +89,16 @@ public class PumpState {
@Override
public String toString() {
return "PumpState{" +
"tbrActive=" + tbrActive +
"timestamp=" + timestamp +
", tbrActive=" + tbrActive +
", tbrPercent=" + tbrPercent +
", tbrRate=" + tbrRate +
", tbrRemainingDuration=" + tbrRemainingDuration +
", errorMsg=" + errorMsg +
", errorMsg='" + errorMsg + '\'' +
", suspended=" + suspended +
", lowBattery=" + lowBattery +
", batteryState=" + batteryState +
", insulinState=" + insulinState +
", reversoirLevel=" + reservoirLevel +
", timestamp=" + timestamp +
", activeBasalProfileNumber=" + activeBasalProfileNumber +
'}';
}
}

View file

@ -2,12 +2,14 @@ package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi;
import java.util.Date;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.PumpHistoryRequest;
public interface RuffyCommands {
CommandResult deliverBolus(double amount, BolusProgressReporter bolusProgressReporter);
void cancelBolus();
CommandResult setTbr(int percent, int duraton);
CommandResult setTbr(int percent, int duration);
CommandResult cancelTbr();
@ -15,12 +17,9 @@ public interface RuffyCommands {
boolean isPumpBusy();
CommandResult readReservoirLevel();
CommandResult readHistory(PumpHistoryRequest request);
// PumpHistory.fields.*: null=don't care. empty history=we know nothing yet. filled history=this is what we know so far
CommandResult readHistory(PumpHistory knownHistory);
CommandResult readBasalProfile();
CommandResult readBasalProfile(int number);
CommandResult setBasalProfile(BasalProfile basalProfile);

View file

@ -0,0 +1,10 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history;
public class Bolus extends HistoryRecord {
public final double amount;
public Bolus(long timestamp, double amount) {
super(timestamp);
this.amount = amount;
}
}

View file

@ -0,0 +1,14 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history;
public class Error extends HistoryRecord {
/** Code is an E for error or W for warning, followed by a single digit, e.g. W7 (TBR cancelled). */
public final String code;
/** Error message, in the language configured on the pump. */
public final String message;
public Error(long timestamp, String code, String message) {
super(timestamp);
this.code = code;
this.message = message;
}
}

View file

@ -0,0 +1,9 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history;
public abstract class HistoryRecord {
public final long timestamp;
protected HistoryRecord(long timestamp) {
this.timestamp = timestamp;
}
}

View file

@ -0,0 +1,31 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history;
import android.support.annotation.NonNull;
import java.lang.*;
import java.util.List;
import java.util.Objects;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.Bolus;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.Tbr;
import info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history.Tdd;
public class PumpHistory {
public final int reservoirLevel;
@NonNull
public final List<Bolus> bolusHistory;
@NonNull
public final List<Tbr> tbrHistory;
@NonNull
public final List<java.lang.Error> errorHistory;
@NonNull
public final List<Tdd> tddHistory;
public PumpHistory(int reservoirLevel, List<Bolus> bolusHistory, List<Tbr> tbrHistory, List<java.lang.Error> errorHistory, List<Tdd> tddHistory) {
this.reservoirLevel = reservoirLevel;
this.bolusHistory = Objects.requireNonNull(bolusHistory);
this.tbrHistory = Objects.requireNonNull(tbrHistory);
this.errorHistory = Objects.requireNonNull(errorHistory);
this.tddHistory = Objects.requireNonNull(tddHistory);
}
}

View file

@ -0,0 +1,47 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history;
/** What data a 'read history' request should return. */
public class PumpHistoryRequest {
public boolean reservoirLevel;
/* History to read:
Either the timestamp of the last known record to fetch all newer records,
or one of the constants to read no history or all of it.
*/
public static final long SKIP = -1;
public static final long FULL = 0;
public long bolusHistory;
public long tbrHistory;
public long errorHistory;
public PumpHistoryRequest reservoirLevel(boolean reservoirLevel) {
this.reservoirLevel = reservoirLevel;
return this;
}
public PumpHistoryRequest bolusHistory(long bolusHistory) {
this.bolusHistory = bolusHistory;
return this;
}
public PumpHistoryRequest tbrHistory(long tbrHistory) {
this.tbrHistory = tbrHistory;
return this;
}
public PumpHistoryRequest errorHistory(long errorHistory) {
this.errorHistory = errorHistory;
return this;
}
@Override
public String toString() {
return "PumpHistoryRequest{" +
"reservoirLevel=" + reservoirLevel +
", bolusHistory=" + bolusHistory +
", tbrHistory=" + tbrHistory +
", errorHistory=" + errorHistory +
'}';
}
}

View file

@ -0,0 +1,12 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history;
public class Tbr extends HistoryRecord {
public final int duration;
public final int percent;
public Tbr(long timestamp, int duration, int percent) {
super(timestamp);
this.duration = duration;
this.percent = percent;
}
}

View file

@ -0,0 +1,11 @@
package info.nightscout.androidaps.plugins.PumpCombo.ruffy.spi.history;
/** Total daily dosage; amount of insulin delivered over a full day. */
public class Tdd extends HistoryRecord {
public final double total;
public Tdd(long timestamp, double total) {
super(timestamp);
this.total = total;
}
}