package com.beowulfe.hap.characteristics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.json.JsonNumber;
import javax.json.JsonObjectBuilder;
import javax.json.JsonValue;
import java.util.concurrent.CompletableFuture;
/**
* A characteristic that provides a Float value type.
*
* @author Andy Lintner
*/
public abstract class FloatCharacteristic extends BaseCharacteristic<Double> {
private final static Logger LOGGER = LoggerFactory.getLogger(FloatCharacteristic.class);
private final double minValue;
private final double maxValue;
private final double minStep;
private final String unit;
/**
* Default constructor
*
* @param type a string containing a UUID that indicates the type of characteristic. Apple defines a set of these,
* however implementors can create their own as well.
* @param isWritable indicates whether the value can be changed.
* @param isReadable indicates whether the value can be retrieved.
* @param description a description of the characteristic to be passed to the consuming device.
* @param minValue the minimum supported value.
* @param maxValue the maximum supported value
* @param minStep the smallest supported step. Values will be rounded to a multiple of this.
* @param unit a description of the unit this characteristic supports.
*/
public FloatCharacteristic(String type, boolean isWritable, boolean isReadable, String description,
double minValue, double maxValue, double minStep, String unit) {
super(type, "float", isWritable, isReadable, description);
this.minValue = minValue;
this.maxValue = maxValue;
this.minStep = minStep;
this.unit = unit;
}
/**
* {@inheritDoc}
*/
@Override
protected CompletableFuture<JsonObjectBuilder> makeBuilder(int iid) {
return super.makeBuilder(iid).thenApply(builder -> builder
.add("minValue", minValue)
.add("maxValue", maxValue)
.add("minStep", minStep)
.add("unit", unit));
}
/**
* {@inheritDoc}
*/
@Override
protected Double convert(JsonValue jsonValue) {
return ((JsonNumber) jsonValue).doubleValue();
}
/**
* {@inheritDoc}. Calls the getDoubleValue method and applies rounding to the minStep supplied in the constructor.
*/
@Override
protected final CompletableFuture<Double> getValue() {
double rounder = 1 / this.minStep;
return getDoubleValue().thenApply(d -> d == null ? null : Math.round(d * rounder) / rounder)
.thenApply(d -> {
if (d != null) {
if (d < minValue) {
LOGGER.warn("Detected value out of range " + d
+ ". Returning min value instead. Characteristic " + this);
return minValue;
}
if (d > maxValue) {
LOGGER.warn("Detected value out of range " + d
+ ". Returning max value instead. Characteristic " + this);
return maxValue;
}
return d;
}
return null;
});
}
/**
* {@inheritDoc}
*/
@Override
protected Double getDefault() {
return minValue;
}
/**
* Supplies the value of this characteristic as a double.
* @return a future that will contain the value.
*/
protected abstract CompletableFuture<Double> getDoubleValue();
}