[homekit] fix optional characteristics (#17038)

* [homekit] fix optional characteristics

Signed-off-by: Cody Cutrer <cody@cutrer.us>
Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
Cody Cutrer 2024-07-14 11:01:36 -06:00 committed by Ciprian Pascu
parent 98ee2e31f9
commit 468b29549b
37 changed files with 68 additions and 69 deletions

View File

@ -228,6 +228,25 @@ public abstract class AbstractHomekitAccessoryImpl implements HomekitAccessory {
return this.services; return this.services;
} }
public void addService(Service service) {
services.add(service);
var serviceClass = service.getClass();
rawCharacteristics.values().forEach(characteristic -> {
// belongs on the accessory information service
if (characteristic.getClass() == NameCharacteristic.class) {
return;
}
try {
// if the service supports adding this characteristic as optional, add it!
serviceClass.getMethod("addOptionalCharacteristic", characteristic.getClass()).invoke(service,
characteristic);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
// the service doesn't support this optional characteristic; ignore it
}
});
}
protected HomekitAccessoryUpdater getUpdater() { protected HomekitAccessoryUpdater getUpdater() {
return updater; return updater;
} }

View File

@ -45,7 +45,7 @@ public class HomekitAirQualitySensorImpl extends AbstractHomekitAccessoryImpl im
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new AirQualityService(this)); addService(new AirQualityService(this));
} }
@Override @Override

View File

@ -45,7 +45,7 @@ class HomekitBasicFanImpl extends AbstractHomekitAccessoryImpl implements BasicF
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
this.getServices().add(new BasicFanService(this)); addService(new BasicFanService(this));
} }
@Override @Override

View File

@ -62,7 +62,7 @@ public class HomekitBatteryImpl extends AbstractHomekitAccessoryImpl implements
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new BatteryService(this)); addService(new BatteryService(this));
} }
@Override @Override

View File

@ -46,7 +46,7 @@ public class HomekitCarbonDioxideSensorImpl extends AbstractHomekitAccessoryImpl
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new CarbonDioxideSensorService(this)); addService(new CarbonDioxideSensorService(this));
} }
@Override @Override

View File

@ -46,7 +46,7 @@ public class HomekitCarbonMonoxideSensorImpl extends AbstractHomekitAccessoryImp
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new CarbonMonoxideSensorService(this)); addService(new CarbonMonoxideSensorService(this));
} }
@Override @Override

View File

@ -44,7 +44,7 @@ public class HomekitContactSensorImpl extends AbstractHomekitAccessoryImpl imple
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new ContactSensorService(this)); addService(new ContactSensorService(this));
} }
@Override @Override

View File

@ -41,7 +41,7 @@ public class HomekitDoorImpl extends AbstractHomekitPositionAccessoryImpl implem
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new DoorService(this)); addService(new DoorService(this));
} }
@Override @Override

View File

@ -43,7 +43,7 @@ class HomekitFanImpl extends AbstractHomekitAccessoryImpl implements FanAccessor
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
this.getServices().add(new FanService(this)); addService(new FanService(this));
} }
@Override @Override

View File

@ -43,7 +43,7 @@ class HomekitFaucetImpl extends AbstractHomekitAccessoryImpl implements FaucetAc
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
this.getServices().add(new FaucetService(this)); addService(new FaucetService(this));
} }
@Override @Override

View File

@ -45,7 +45,7 @@ public class HomekitFilterMaintenanceImpl extends AbstractHomekitAccessoryImpl i
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new FilterMaintenanceService(this)); addService(new FilterMaintenanceService(this));
} }
@Override @Override

View File

@ -55,7 +55,7 @@ public class HomekitGarageDoorOpenerImpl extends AbstractHomekitAccessoryImpl im
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new GarageDoorOpenerService(this)); addService(new GarageDoorOpenerService(this));
} }
@Override @Override

View File

@ -73,10 +73,10 @@ public class HomekitHeaterCoolerImpl extends AbstractHomekitAccessoryImpl implem
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
final HeaterCoolerService service = new HeaterCoolerService(this); final HeaterCoolerService service = new HeaterCoolerService(this);
addService(service);
service.addOptionalCharacteristic(new TemperatureDisplayUnitCharacteristic(this::getTemperatureDisplayUnit, service.addOptionalCharacteristic(new TemperatureDisplayUnitCharacteristic(this::getTemperatureDisplayUnit,
this::setTemperatureDisplayUnit, this::subscribeTemperatureDisplayUnit, this::setTemperatureDisplayUnit, this::subscribeTemperatureDisplayUnit,
this::unsubscribeTemperatureDisplayUnit)); this::unsubscribeTemperatureDisplayUnit));
getServices().add(service);
} }
@Override @Override

View File

@ -43,7 +43,7 @@ public class HomekitHumiditySensorImpl extends AbstractHomekitAccessoryImpl impl
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new HumiditySensorService(this)); addService(new HumiditySensorService(this));
} }
@Override @Override

View File

@ -28,10 +28,8 @@ import io.github.hapjava.characteristics.impl.common.IsConfiguredCharacteristic;
import io.github.hapjava.characteristics.impl.common.IsConfiguredEnum; import io.github.hapjava.characteristics.impl.common.IsConfiguredEnum;
import io.github.hapjava.characteristics.impl.inputsource.CurrentVisibilityStateCharacteristic; import io.github.hapjava.characteristics.impl.inputsource.CurrentVisibilityStateCharacteristic;
import io.github.hapjava.characteristics.impl.inputsource.CurrentVisibilityStateEnum; import io.github.hapjava.characteristics.impl.inputsource.CurrentVisibilityStateEnum;
import io.github.hapjava.characteristics.impl.inputsource.InputDeviceTypeCharacteristic;
import io.github.hapjava.characteristics.impl.inputsource.InputSourceTypeCharacteristic; import io.github.hapjava.characteristics.impl.inputsource.InputSourceTypeCharacteristic;
import io.github.hapjava.characteristics.impl.inputsource.InputSourceTypeEnum; import io.github.hapjava.characteristics.impl.inputsource.InputSourceTypeEnum;
import io.github.hapjava.characteristics.impl.inputsource.TargetVisibilityStateCharacteristic;
import io.github.hapjava.services.impl.InputSourceService; import io.github.hapjava.services.impl.InputSourceService;
/** /**
@ -78,18 +76,16 @@ public class HomekitInputSourceImpl extends AbstractHomekitAccessoryImpl {
() -> CompletableFuture.completedFuture(CurrentVisibilityStateEnum.SHOWN), v -> { () -> CompletableFuture.completedFuture(CurrentVisibilityStateEnum.SHOWN), v -> {
}, () -> { }, () -> {
})); }));
var identifierCharacteristic = getCharacteristic(IdentifierCharacteristic.class)
.orElseGet(() -> new IdentifierCharacteristic(() -> CompletableFuture.completedFuture(1)));
var service = new InputSourceService(configuredNameCharacteristic, inputSourceTypeCharacteristic, var service = new InputSourceService(configuredNameCharacteristic, inputSourceTypeCharacteristic,
isConfiguredCharacteristic, currentVisibilityStateCharacteristic); isConfiguredCharacteristic, currentVisibilityStateCharacteristic);
service.addOptionalCharacteristic(identifierCharacteristic); var identifierCharacteristic = getCharacteristic(IdentifierCharacteristic.class);
getCharacteristic(InputDeviceTypeCharacteristic.class).ifPresent(c -> service.addOptionalCharacteristic(c)); if (identifierCharacteristic.isEmpty()) {
getCharacteristic(TargetVisibilityStateCharacteristic.class) service.addOptionalCharacteristic(new IdentifierCharacteristic(() -> CompletableFuture.completedFuture(1)));
.ifPresent(c -> service.addOptionalCharacteristic(c)); }
getServices().add(service); addService(service);
} }
@Override @Override

View File

@ -55,7 +55,7 @@ public class HomekitIrrigationSystemImpl extends AbstractHomekitAccessoryImpl im
inUseMapping = createMapping(HomekitCharacteristicType.INUSE_STATUS, InUseEnum.class); inUseMapping = createMapping(HomekitCharacteristicType.INUSE_STATUS, InUseEnum.class);
programModeMap = HomekitCharacteristicFactory programModeMap = HomekitCharacteristicFactory
.createMapping(getCharacteristic(HomekitCharacteristicType.PROGRAM_MODE).get(), ProgramModeEnum.class); .createMapping(getCharacteristic(HomekitCharacteristicType.PROGRAM_MODE).get(), ProgramModeEnum.class);
getServices().add(new IrrigationSystemService(this)); addService(new IrrigationSystemService(this));
} }
@Override @Override
@ -73,7 +73,7 @@ public class HomekitIrrigationSystemImpl extends AbstractHomekitAccessoryImpl im
final var finalEnum = serviceLabelEnum; final var finalEnum = serviceLabelEnum;
var serviceLabelNamespace = getCharacteristic(ServiceLabelNamespaceCharacteristic.class).orElseGet( var serviceLabelNamespace = getCharacteristic(ServiceLabelNamespaceCharacteristic.class).orElseGet(
() -> new ServiceLabelNamespaceCharacteristic(() -> CompletableFuture.completedFuture(finalEnum))); () -> new ServiceLabelNamespaceCharacteristic(() -> CompletableFuture.completedFuture(finalEnum)));
getServices().add(new ServiceLabelService(serviceLabelNamespace)); addService(new ServiceLabelService(serviceLabelNamespace));
} }
@Override @Override

View File

@ -44,7 +44,7 @@ public class HomekitLeakSensorImpl extends AbstractHomekitAccessoryImpl implemen
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new LeakSensorService(this)); addService(new LeakSensorService(this));
} }
@Override @Override

View File

@ -46,7 +46,7 @@ public class HomekitLightSensorImpl extends AbstractHomekitAccessoryImpl impleme
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new LightSensorService(this)); addService(new LightSensorService(this));
} }
@Override @Override

View File

@ -44,7 +44,7 @@ class HomekitLightbulbImpl extends AbstractHomekitAccessoryImpl implements Light
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new LightbulbService(this)); addService(new LightbulbService(this));
} }
@Override @Override

View File

@ -49,7 +49,7 @@ public class HomekitLockImpl extends AbstractHomekitAccessoryImpl implements Loc
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new LockMechanismService(this)); addService(new LockMechanismService(this));
} }
@Override @Override

View File

@ -42,7 +42,7 @@ public class HomekitMicrophoneImpl extends AbstractHomekitAccessoryImpl implemen
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new MicrophoneService(this)); addService(new MicrophoneService(this));
} }
@Override @Override

View File

@ -41,7 +41,7 @@ public class HomekitMotionSensorImpl extends AbstractHomekitAccessoryImpl implem
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new MotionSensorService(this)); addService(new MotionSensorService(this));
} }
@Override @Override

View File

@ -44,7 +44,7 @@ public class HomekitOccupancySensorImpl extends AbstractHomekitAccessoryImpl imp
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new OccupancySensorService(this)); addService(new OccupancySensorService(this));
} }
@Override @Override

View File

@ -43,7 +43,7 @@ public class HomekitOutletImpl extends AbstractHomekitAccessoryImpl implements O
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new OutletService(this)); addService(new OutletService(this));
} }
@Override @Override

View File

@ -59,7 +59,7 @@ public class HomekitSecuritySystemImpl extends AbstractHomekitAccessoryImpl impl
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new SecuritySystemService(this)); addService(new SecuritySystemService(this));
} }
@Override @Override

View File

@ -49,7 +49,7 @@ public class HomekitSlatImpl extends AbstractHomekitAccessoryImpl implements Sla
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new SlatService(this)); addService(new SlatService(this));
} }
@Override @Override

View File

@ -48,7 +48,7 @@ public class HomekitSmartSpeakerImpl extends AbstractHomekitAccessoryImpl implem
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new SmartSpeakerService(this)); addService(new SmartSpeakerService(this));
} }
@Override @Override

View File

@ -44,7 +44,7 @@ public class HomekitSmokeSensorImpl extends AbstractHomekitAccessoryImpl impleme
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
this.getServices().add(new SmokeSensorService(this)); addService(new SmokeSensorService(this));
} }
@Override @Override

View File

@ -42,7 +42,7 @@ public class HomekitSpeakerImpl extends AbstractHomekitAccessoryImpl implements
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new SpeakerService(this)); addService(new SpeakerService(this));
} }
@Override @Override

View File

@ -43,7 +43,7 @@ public class HomekitSwitchImpl extends AbstractHomekitAccessoryImpl implements S
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new SwitchService(this)); addService(new SwitchService(this));
} }
@Override @Override

View File

@ -24,15 +24,9 @@ import org.openhab.io.homekit.internal.HomekitTaggedItem;
import io.github.hapjava.characteristics.impl.common.ActiveCharacteristic; import io.github.hapjava.characteristics.impl.common.ActiveCharacteristic;
import io.github.hapjava.characteristics.impl.common.ActiveIdentifierCharacteristic; import io.github.hapjava.characteristics.impl.common.ActiveIdentifierCharacteristic;
import io.github.hapjava.characteristics.impl.common.ConfiguredNameCharacteristic; import io.github.hapjava.characteristics.impl.common.ConfiguredNameCharacteristic;
import io.github.hapjava.characteristics.impl.lightbulb.BrightnessCharacteristic;
import io.github.hapjava.characteristics.impl.television.ClosedCaptionsCharacteristic;
import io.github.hapjava.characteristics.impl.television.CurrentMediaStateCharacteristic;
import io.github.hapjava.characteristics.impl.television.PictureModeCharacteristic;
import io.github.hapjava.characteristics.impl.television.PowerModeCharacteristic;
import io.github.hapjava.characteristics.impl.television.RemoteKeyCharacteristic; import io.github.hapjava.characteristics.impl.television.RemoteKeyCharacteristic;
import io.github.hapjava.characteristics.impl.television.SleepDiscoveryModeCharacteristic; import io.github.hapjava.characteristics.impl.television.SleepDiscoveryModeCharacteristic;
import io.github.hapjava.characteristics.impl.television.SleepDiscoveryModeEnum; import io.github.hapjava.characteristics.impl.television.SleepDiscoveryModeEnum;
import io.github.hapjava.characteristics.impl.television.TargetMediaStateCharacteristic;
import io.github.hapjava.services.impl.TelevisionService; import io.github.hapjava.services.impl.TelevisionService;
/** /**
@ -81,13 +75,6 @@ public class HomekitTelevisionImpl extends AbstractHomekitAccessoryImpl {
activeIdentifierCharacteristic, configuredNameCharacteristic, remoteKeyCharacteristic, activeIdentifierCharacteristic, configuredNameCharacteristic, remoteKeyCharacteristic,
sleepDiscoveryModeCharacteristic); sleepDiscoveryModeCharacteristic);
getCharacteristic(BrightnessCharacteristic.class).ifPresent(c -> service.addOptionalCharacteristic(c)); addService(service);
getCharacteristic(PowerModeCharacteristic.class).ifPresent(c -> service.addOptionalCharacteristic(c));
getCharacteristic(ClosedCaptionsCharacteristic.class).ifPresent(c -> service.addOptionalCharacteristic(c));
getCharacteristic(CurrentMediaStateCharacteristic.class).ifPresent(c -> service.addOptionalCharacteristic(c));
getCharacteristic(TargetMediaStateCharacteristic.class).ifPresent(c -> service.addOptionalCharacteristic(c));
getCharacteristic(PictureModeCharacteristic.class).ifPresent(c -> service.addOptionalCharacteristic(c));
getServices().add(service);
} }
} }

View File

@ -13,7 +13,6 @@
package org.openhab.io.homekit.internal.accessories; package org.openhab.io.homekit.internal.accessories;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@ -25,7 +24,6 @@ import org.openhab.io.homekit.internal.HomekitTaggedItem;
import io.github.hapjava.characteristics.impl.audio.MuteCharacteristic; import io.github.hapjava.characteristics.impl.audio.MuteCharacteristic;
import io.github.hapjava.characteristics.impl.audio.VolumeCharacteristic; import io.github.hapjava.characteristics.impl.audio.VolumeCharacteristic;
import io.github.hapjava.characteristics.impl.common.ActiveCharacteristic;
import io.github.hapjava.characteristics.impl.televisionspeaker.VolumeControlTypeCharacteristic; import io.github.hapjava.characteristics.impl.televisionspeaker.VolumeControlTypeCharacteristic;
import io.github.hapjava.characteristics.impl.televisionspeaker.VolumeControlTypeEnum; import io.github.hapjava.characteristics.impl.televisionspeaker.VolumeControlTypeEnum;
import io.github.hapjava.characteristics.impl.televisionspeaker.VolumeSelectorCharacteristic; import io.github.hapjava.characteristics.impl.televisionspeaker.VolumeSelectorCharacteristic;
@ -61,6 +59,8 @@ public class HomekitTelevisionSpeakerImpl extends AbstractHomekitAccessoryImpl {
var volumeCharacteristic = getCharacteristic(VolumeCharacteristic.class); var volumeCharacteristic = getCharacteristic(VolumeCharacteristic.class);
var volumeSelectorCharacteristic = getCharacteristic(VolumeSelectorCharacteristic.class); var volumeSelectorCharacteristic = getCharacteristic(VolumeSelectorCharacteristic.class);
var service = new TelevisionSpeakerService(muteCharacteristic);
if (volumeControlTypeCharacteristic.isEmpty()) { if (volumeControlTypeCharacteristic.isEmpty()) {
VolumeControlTypeEnum type; VolumeControlTypeEnum type;
if (volumeCharacteristic.isPresent()) { if (volumeCharacteristic.isPresent()) {
@ -70,18 +70,12 @@ public class HomekitTelevisionSpeakerImpl extends AbstractHomekitAccessoryImpl {
} else { } else {
type = VolumeControlTypeEnum.NONE; type = VolumeControlTypeEnum.NONE;
} }
volumeControlTypeCharacteristic = Optional service.addOptionalCharacteristic(
.of(new VolumeControlTypeCharacteristic(() -> CompletableFuture.completedFuture(type), v -> { new VolumeControlTypeCharacteristic(() -> CompletableFuture.completedFuture(type), v -> {
}, () -> { }, () -> {
})); }));
} }
var service = new TelevisionSpeakerService(muteCharacteristic); addService(service);
getCharacteristic(ActiveCharacteristic.class).ifPresent(c -> service.addOptionalCharacteristic(c));
volumeCharacteristic.ifPresent(c -> service.addOptionalCharacteristic(c));
service.addOptionalCharacteristic(volumeControlTypeCharacteristic.get());
getServices().add(service);
} }
} }

View File

@ -44,7 +44,7 @@ class HomekitTemperatureSensorImpl extends AbstractHomekitAccessoryImpl implemen
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new TemperatureSensorService(this)); addService(new TemperatureSensorService(this));
} }
@Override @Override

View File

@ -73,7 +73,7 @@ class HomekitThermostatImpl extends AbstractHomekitAccessoryImpl implements Ther
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
this.getServices().add(new ThermostatService(this)); addService(new ThermostatService(this));
} }
@Override @Override

View File

@ -87,8 +87,11 @@ public class HomekitValveImpl extends AbstractHomekitAccessoryImpl implements Va
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
ValveService service = new ValveService(this); ValveService service = new ValveService(this);
getServices().add(service); addService(service);
if (homekitTimer) {
var remainingDurationCharacteristic = getCharacteristic(RemainingDurationCharacteristic.class);
if (homekitTimer && remainingDurationCharacteristic.isEmpty()) {
addRemainingDurationCharacteristic(getRootAccessory(), getUpdater(), service); addRemainingDurationCharacteristic(getRootAccessory(), getUpdater(), service);
} }
String valveTypeConfig = getAccessoryConfiguration(CONFIG_VALVE_TYPE, "GENERIC"); String valveTypeConfig = getAccessoryConfiguration(CONFIG_VALVE_TYPE, "GENERIC");

View File

@ -41,7 +41,7 @@ public class HomekitWindowCoveringImpl extends AbstractHomekitPositionAccessoryI
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new WindowCoveringService(this)); addService(new WindowCoveringService(this));
} }
@Override @Override

View File

@ -41,7 +41,7 @@ public class HomekitWindowImpl extends AbstractHomekitPositionAccessoryImpl impl
@Override @Override
public void init() throws HomekitException { public void init() throws HomekitException {
super.init(); super.init();
getServices().add(new WindowService(this)); addService(new WindowService(this));
} }
@Override @Override