package dk.silverbullet.telemed.device.andweightscale.packet.input;
import dk.silverbullet.telemed.device.UnexpectedPacketFormatException;
import dk.silverbullet.telemed.device.andweightscale.Weight;
import dk.silverbullet.telemed.device.andweightscale.Weight.Unit;
import dk.silverbullet.telemed.device.continua.packet.input.ConfirmedMeasurementDataPacket;
import dk.silverbullet.telemed.device.continua.packet.input.OrderedByteReader;
import java.io.IOException;
public class AndWeightScaleConfirmedMeasurementDataPacket extends ConfirmedMeasurementDataPacket {
private static final int NUMBER_OF_DECIMALS_1 = 0xFF00;
private static final int NUMBER_OF_DECIMALS_2 = 0xFE00;
private static final int MDC_DIM_KILO_G = 0x06C3;
private static final int MDC_DIM_LB = 0x06E0;
private static final long NO_TIME = -1;
private long newestTimestamp;
private Weight newestWeight;
public AndWeightScaleConfirmedMeasurementDataPacket(byte[] contents) throws IOException {
super(contents);
}
protected void readObjects(int eventType, OrderedByteReader in) throws IOException {
if (eventType != MDC_NOTI_SCAN_REPORT_VAR) {
throw new UnexpectedPacketFormatException("Unexpected event-type 0x" + Integer.toString(eventType, 16)
+ " (expected 0x0D1E)");
}
newestTimestamp = NO_TIME;
int numberOfMeasurements = in.readShort(); // ScanReportInfoFixed.obs-scan-fixed.count
in.readShort(); // ScanReportInfoFixed.obs-scan-fixed.length
for (int i = 0; i < numberOfMeasurements; i++) {
checkShort(in, "obj-handle", 0x0001);
checkShort(in, "Number of attributes?", 0x0003);
checkShort(in, "Length of measurement", 0x001A);
checkShort(in, "??", 0x0A56);
float weight = readWeight(in);
long timestamp = readTimestamp(in);
Unit unit = readUnit(in);
if (timestamp > newestTimestamp) {
newestWeight = new Weight(weight, unit);
newestTimestamp = timestamp;
}
}
}
private float readWeight(OrderedByteReader in) throws IOException {
checkShort(in, "Length of nu-observed-value", 0x0004);
float divisionFactor = readDivisionFactor(in);
int weightInSomeUnit = in.readShort() & 0xFFFF /* Make unsigned */;
return weightInSomeUnit / divisionFactor;
}
private float readDivisionFactor(OrderedByteReader in) throws IOException {
int baseCode = in.readShort();
if (baseCode == NUMBER_OF_DECIMALS_1) {
return 10;
}
if (baseCode == NUMBER_OF_DECIMALS_2) {
return 100;
}
throw new UnexpectedPacketFormatException("Unexpected base code 0x" + Integer.toString(baseCode, 16)
+ "(expected 0xFF00 or 0xFE00)");
}
private long readTimestamp(OrderedByteReader in) throws IOException {
checkShort(in, "MDC_ATTR_TIME_STAMP_ABS", 0x0990);
checkShort(in, "Length of timestamp", 0x0008);
return in.readLong();
}
private Unit readUnit(OrderedByteReader in) throws IOException {
checkShort(in, "MDC_ATTR_UNIT_CODE", 0x0996);
checkShort(in, "Length of unit code", 0x0002);
int unitCode = in.readShort();
if (unitCode == MDC_DIM_KILO_G) {
return Unit.KG;
}
if (unitCode == MDC_DIM_LB) {
return Unit.LBS;
}
throw new UnexpectedPacketFormatException("Unexpected unit code 0x" + Integer.toString(unitCode, 16)
+ "(expected 0x06C3 or 0x06E0)");
}
public Weight getWeight() {
return newestWeight;
}
public long getTimestamp() {
return newestTimestamp;
}
@Override
public String toString() {
return "AndWeightScaleConfirmedMeasurementDataPacket [newestTimestamp=0x" + Long.toString(newestTimestamp, 16)
+ ", newestWeight=" + newestWeight + "]";
}
}