Description
TL;DR
The current mechanism of implementing additional interfaces to add support for optional characteristics is non-conducive to supporting dynamic sets of optional characteristics.
Background and current workaround
In my fork of Openhab-homekit, I support low battery notification. However, whether or not an accessory actually has low-battery notification support is based on the items configuration. As a workaround, in order to avoid creating two classes for sensors that potentially have battery status reporting support, I create a faux-battery notification implementation that always returns batteryLow=false).
Limitations of providing substitute static-values
Such workarounds are not possible when adding a characteristic that fundamentally changes the presentation of an accessory in homekit. For example, with the thermostat, the addition of optional characteristics Characteristic.CoolingThresholdTemperature
and Characteristic.HeatingThresholdTemperature
causes the UI to show a temperature range, rather than a single temperature, when the AUTO TargetCoolingHeatingState is active.
Proposal and way forward
I propose that accessories classes only specify getters, setters, and subscribers for their base class.
Then, for optional characteristics, I propose that the accessory has an overridable getter which gets some optional characteristic, with the default value being none:
@Override
protected Optional<HeatingThresholdCharacteristicSupport> heatingThresholdTemperatureCharacteristic() {
heatingThresholdItem.map(item -> {
new HeatingThresholdCharacteristicSupport() {
@Override
CompletableFuture<Double> getHeatingThresholdTemperature() {
...
}
...
}
});
}
The HeatingThermostat
trait can be modified such that the interface methods are lifted out in to HeatingThresholdCharacteristicSupport
, retaining backwards compatibility (and potentially marking as deprecated for removal in next minor release of HAP-Java). After such a lift, the interface would be effectively empty:
package com.beowulfe.hap.accessories.thermostat;
import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
import java.util.concurrent.CompletableFuture;
@Deprecated
public interface HeatingThermostat extends BasicThermostat, HeatingThresholdCharacteristicSupport {
}