package org.openaltimeter.settings;
import org.openaltimeter.TypeConverter;
public class Settings {
public enum BatteryType {
NIMH, LIPO, NONE
};
public enum Action {
DO_NOTHING, OUTPUT_MAX_HEIGHT, OUTPUT_MAX_LAUNCH_HEIGHT,
OUTPUT_LAUNCH_WINDOW_END_HEIGHT, OUTPUT_BATTERY_VOLTAGE
};
public static int SETTINGS_SIZE = 21;
public int logIntervalMS;
public float heightUnits;
public BatteryType batteryType;
// if the battery type is NIMH, then this is the threshold, for LIPO it's
// the per cell threshold
public float lowVoltageThreshold;
public float batteryMonitorCalibration;
public boolean logServo;
public Action midPositionAction;
public Action onPositionAction;
// creates the settings object from a stream of bytes, as output by the
// OA board
public Settings(byte[] bytes) {
parseBytes(bytes);
}
public Settings() {
}
public boolean equals(Settings other) {
return ((logIntervalMS == other.logIntervalMS) && (heightUnits == other.heightUnits)
&& (batteryType == other.batteryType) && (lowVoltageThreshold == other.lowVoltageThreshold)
&& (batteryMonitorCalibration == other.batteryMonitorCalibration) && (logServo == other.logServo)
&& (midPositionAction == other.midPositionAction) && (onPositionAction == other.onPositionAction));
}
private void parseBytes(byte[] bytes) {
logIntervalMS = TypeConverter.bytesToSignedInt(bytes[0], bytes[1], (byte) 0x00, (byte) 0x00);
heightUnits = TypeConverter.bytesToFloat(bytes[2], bytes[3], bytes[4], bytes[5]);
int batteryTypeByte = bytes[6];
switch (batteryTypeByte) {
case 0:
batteryType = BatteryType.NIMH;
break;
case 1:
batteryType = BatteryType.LIPO;
break;
case 2:
batteryType = BatteryType.NONE;
break;
}
lowVoltageThreshold = TypeConverter.bytesToFloat(bytes[8], bytes[9], bytes[10], bytes[11]);
batteryMonitorCalibration = TypeConverter.bytesToFloat(bytes[12], bytes[13], bytes[14], bytes[15]);
logServo = !(bytes[16] == 0);
int midPositionActionByte = bytes[17];
midPositionAction = parseActionByte(midPositionActionByte);
int onPositionActionByte = bytes[19];
onPositionAction = parseActionByte(onPositionActionByte);
}
public Action parseActionByte(int actionByte) {
Action action = Action.DO_NOTHING;
switch (actionByte) {
case 0:
action = Action.DO_NOTHING;
break;
case 1:
action = Action.OUTPUT_MAX_HEIGHT;
break;
case 2:
action = Action.OUTPUT_MAX_LAUNCH_HEIGHT;
break;
case 3:
action = Action.OUTPUT_LAUNCH_WINDOW_END_HEIGHT;
break;
case 4:
action = Action.OUTPUT_BATTERY_VOLTAGE;
break;
}
return action;
}
// produces a byte array suitable for sending to the OA board
public byte[] toByteArray() {
byte[] bytes = new byte[SETTINGS_SIZE];
byte[] liBytes = TypeConverter.unsignedShortToBytes(logIntervalMS);
bytes[0] = liBytes[0];
bytes[1] = liBytes[1];
byte[] huBytes = TypeConverter.floatToBytes(heightUnits);
bytes[2] = huBytes[0];
bytes[3] = huBytes[1];
bytes[4] = huBytes[2];
bytes[5] = huBytes[3];
switch (batteryType) {
case NIMH:
bytes[6] = 0;
break;
case LIPO:
bytes[6] = 1;
break;
case NONE:
bytes[6] = 2;
break;
}
bytes[7] = 0;
byte[] lvBytes = TypeConverter.floatToBytes(lowVoltageThreshold);
bytes[8] = lvBytes[0];
bytes[9] = lvBytes[1];
bytes[10] = lvBytes[2];
bytes[11] = lvBytes[3];
byte[] bmBytes = TypeConverter.floatToBytes(batteryMonitorCalibration);
bytes[12] = bmBytes[0];
bytes[13] = bmBytes[1];
bytes[14] = bmBytes[2];
bytes[15] = bmBytes[3];
bytes[16] = (byte) (logServo ? 1 : 0);
bytes[17] = actionToByte(midPositionAction);
bytes[18] = 0;
bytes[19] = actionToByte(onPositionAction);
bytes[20] = 0;
return bytes;
}
public byte actionToByte(Action a) {
byte b = 0;
switch (a) {
case DO_NOTHING:
b = 0;
break;
case OUTPUT_MAX_HEIGHT:
b = 1;
break;
case OUTPUT_MAX_LAUNCH_HEIGHT:
b = 2;
break;
case OUTPUT_LAUNCH_WINDOW_END_HEIGHT:
b = 3;
break;
case OUTPUT_BATTERY_VOLTAGE:
b = 4;
break;
}
return b;
}
}