Skip to content

Commit

Permalink
[homekit] Make GarageDoorOpener.ObstructionStatus optional (#17137)
Browse files Browse the repository at this point in the history
To simplify linking to "simple" things that don't have it.
It will just always return "not obstructed" if not linked

Signed-off-by: Cody Cutrer <cody@cutrer.us>
  • Loading branch information
ccutrer authored Jul 24, 2024
1 parent 0156612 commit 7303331
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 72 deletions.
2 changes: 1 addition & 1 deletion bundles/org.openhab.io.homekit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -796,8 +796,8 @@ All accessories also support the following optional characteristic that can be l
| | | FilterResetIndication | Switch | Send "filter reset" action triggered by user in iOS Home app to openHAB ("ON" = reset requested by user). | | |
| GarageDoorOpener | | | | A garage door opener. | | |
| | CurrentDoorState | | Contact, Switch, Number, String | Current door state. | inverted (false) | OPEN (0, ON, OPEN), CLOSED (1, OFF, CLOSED), OPENING (2), CLOSING (3), STOPPED (4) |
| | ObstructionStatus | | Contact, Switch | Current status of obstruction sensor. ON-obstruction detected, OFF - no obstruction | inverted (false) | |
| | TargetDoorState | | Contact, Switch, Number, String | Target door state. | inverted (false) | OPEN (0, ON, OPEN), CLOSED (1, OFF, CLOSED) |
| | | ObstructionStatus | Contact, Switch | Current status of obstruction sensor. ON-obstruction detected, OFF - no obstruction | inverted (false) | |
| HeaterCooler | | | | Heater or/and cooler device | | |
| | ActiveStatus | | Dimmer, Switch | Accessory current working status. A value of "ON"/"OPEN" indicates that the accessory is active and is functioning without any errors. | | |
| | CurrentHeaterCoolerState | | Number, String | Current heater/cooler mode. | | INACTIVE (0), IDLE (1), HEATING (2), COOLING (3) |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ public class HomekitAccessoryFactory {
put(FAN, new HomekitCharacteristicType[] { ACTIVE_STATUS });
put(FAUCET, new HomekitCharacteristicType[] { ACTIVE_STATUS });
put(FILTER_MAINTENANCE, new HomekitCharacteristicType[] { FILTER_CHANGE_INDICATION });
put(GARAGE_DOOR_OPENER,
new HomekitCharacteristicType[] { CURRENT_DOOR_STATE, TARGET_DOOR_STATE, OBSTRUCTION_STATUS });
put(GARAGE_DOOR_OPENER, new HomekitCharacteristicType[] { CURRENT_DOOR_STATE, TARGET_DOOR_STATE });
put(HEATER_COOLER, new HomekitCharacteristicType[] { ACTIVE_STATUS, CURRENT_HEATER_COOLER_STATE,
TARGET_HEATER_COOLER_STATE, CURRENT_TEMPERATURE });
put(HUMIDITY_SENSOR, new HomekitCharacteristicType[] { RELATIVE_HUMIDITY });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@
import io.github.hapjava.characteristics.impl.fan.TargetFanStateEnum;
import io.github.hapjava.characteristics.impl.filtermaintenance.FilterLifeLevelCharacteristic;
import io.github.hapjava.characteristics.impl.filtermaintenance.ResetFilterIndicationCharacteristic;
import io.github.hapjava.characteristics.impl.garagedoor.CurrentDoorStateCharacteristic;
import io.github.hapjava.characteristics.impl.garagedoor.CurrentDoorStateEnum;
import io.github.hapjava.characteristics.impl.garagedoor.TargetDoorStateCharacteristic;
import io.github.hapjava.characteristics.impl.garagedoor.TargetDoorStateEnum;
import io.github.hapjava.characteristics.impl.humiditysensor.CurrentRelativeHumidityCharacteristic;
import io.github.hapjava.characteristics.impl.humiditysensor.TargetRelativeHumidityCharacteristic;
import io.github.hapjava.characteristics.impl.inputsource.CurrentVisibilityStateCharacteristic;
Expand Down Expand Up @@ -197,6 +201,7 @@ public class HomekitCharacteristicFactory {
put(CONFIGURED, HomekitCharacteristicFactory::createIsConfiguredCharacteristic);
put(CONFIGURED_NAME, HomekitCharacteristicFactory::createConfiguredNameCharacteristic);
put(COOLING_THRESHOLD_TEMPERATURE, HomekitCharacteristicFactory::createCoolingThresholdCharacteristic);
put(CURRENT_DOOR_STATE, HomekitCharacteristicFactory::createCurrentDoorStateCharacteristic);
put(CURRENT_HEATING_COOLING_STATE,
HomekitCharacteristicFactory::createCurrentHeatingCoolingStateCharacteristic);
put(CURRENT_FAN_STATE, HomekitCharacteristicFactory::createCurrentFanStateCharacteristic);
Expand Down Expand Up @@ -245,6 +250,7 @@ public class HomekitCharacteristicFactory {
put(SULPHUR_DIOXIDE_DENSITY, HomekitCharacteristicFactory::createSulphurDioxideDensityCharacteristic);
put(SWING_MODE, HomekitCharacteristicFactory::createSwingModeCharacteristic);
put(TAMPERED_STATUS, HomekitCharacteristicFactory::createStatusTamperedCharacteristic);
put(TARGET_DOOR_STATE, HomekitCharacteristicFactory::createTargetDoorStateCharacteristic);
put(TARGET_FAN_STATE, HomekitCharacteristicFactory::createTargetFanStateCharacteristic);
put(TARGET_HEATING_COOLING_STATE,
HomekitCharacteristicFactory::createTargetHeatingCoolingStateCharacteristic);
Expand Down Expand Up @@ -821,6 +827,15 @@ private static CoolingThresholdTemperatureCharacteristic createCoolingThresholdC
getUnsubscriber(taggedItem, COOLING_THRESHOLD_TEMPERATURE, updater));
}

private static CurrentDoorStateCharacteristic createCurrentDoorStateCharacteristic(HomekitTaggedItem taggedItem,
HomekitAccessoryUpdater updater) {
List<CurrentDoorStateEnum> validValues = new ArrayList<>();
var map = createMapping(taggedItem, CurrentDoorStateEnum.class, validValues);
return new CurrentDoorStateCharacteristic(() -> getEnumFromItem(taggedItem, map, CurrentDoorStateEnum.CLOSED),
getSubscriber(taggedItem, CURRENT_DOOR_STATE, updater),
getUnsubscriber(taggedItem, CURRENT_DOOR_STATE, updater));
}

private static CurrentHeatingCoolingStateCharacteristic createCurrentHeatingCoolingStateCharacteristic(
HomekitTaggedItem taggedItem, HomekitAccessoryUpdater updater) {
List<CurrentHeatingCoolingStateEnum> validValues = new ArrayList<>();
Expand Down Expand Up @@ -1366,6 +1381,16 @@ private static SwingModeCharacteristic createSwingModeCharacteristic(HomekitTagg
getUnsubscriber(taggedItem, SWING_MODE, updater));
}

private static TargetDoorStateCharacteristic createTargetDoorStateCharacteristic(HomekitTaggedItem taggedItem,
HomekitAccessoryUpdater updater) {
List<TargetDoorStateEnum> validValues = new ArrayList<>();
var map = createMapping(taggedItem, TargetDoorStateEnum.class, validValues);
return new TargetDoorStateCharacteristic(() -> getEnumFromItem(taggedItem, map, TargetDoorStateEnum.CLOSED),
(targetState) -> setValueFromEnum(taggedItem, targetState, map),
getSubscriber(taggedItem, TARGET_DOOR_STATE, updater),
getUnsubscriber(taggedItem, TARGET_DOOR_STATE, updater));
}

private static TargetFanStateCharacteristic createTargetFanStateCharacteristic(HomekitTaggedItem taggedItem,
HomekitAccessoryUpdater updater) {
var map = createMapping(taggedItem, TargetFanStateEnum.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@
*/
package org.openhab.io.homekit.internal.accessories;

import static org.openhab.io.homekit.internal.HomekitCharacteristicType.CURRENT_DOOR_STATE;
import static org.openhab.io.homekit.internal.HomekitCharacteristicType.OBSTRUCTION_STATUS;
import static org.openhab.io.homekit.internal.HomekitCharacteristicType.TARGET_DOOR_STATE;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import org.openhab.io.homekit.internal.HomekitAccessoryUpdater;
Expand All @@ -27,90 +22,36 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.github.hapjava.accessories.GarageDoorOpenerAccessory;
import io.github.hapjava.characteristics.Characteristic;
import io.github.hapjava.characteristics.HomekitCharacteristicChangeCallback;
import io.github.hapjava.characteristics.impl.garagedoor.CurrentDoorStateEnum;
import io.github.hapjava.characteristics.impl.garagedoor.TargetDoorStateEnum;
import io.github.hapjava.characteristics.impl.common.ObstructionDetectedCharacteristic;
import io.github.hapjava.characteristics.impl.garagedoor.CurrentDoorStateCharacteristic;
import io.github.hapjava.characteristics.impl.garagedoor.TargetDoorStateCharacteristic;
import io.github.hapjava.services.impl.GarageDoorOpenerService;

/**
* Implements Garage Door Opener
*
* @author Eugen Freiter - Initial contribution
*/
public class HomekitGarageDoorOpenerImpl extends AbstractHomekitAccessoryImpl implements GarageDoorOpenerAccessory {
public class HomekitGarageDoorOpenerImpl extends AbstractHomekitAccessoryImpl {
private final Logger logger = LoggerFactory.getLogger(HomekitGarageDoorOpenerImpl.class);
private final BooleanItemReader obstructionReader;
private final Map<CurrentDoorStateEnum, String> currentDoorStateMapping;
private final Map<TargetDoorStateEnum, String> targetDoorStateMapping;

public HomekitGarageDoorOpenerImpl(HomekitTaggedItem taggedItem, List<HomekitTaggedItem> mandatoryCharacteristics,
List<Characteristic> mandatoryRawCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings)
throws IncompleteAccessoryException {
super(taggedItem, mandatoryCharacteristics, mandatoryRawCharacteristics, updater, settings);
obstructionReader = createBooleanReader(OBSTRUCTION_STATUS);
currentDoorStateMapping = createMapping(CURRENT_DOOR_STATE, CurrentDoorStateEnum.class, true);
targetDoorStateMapping = createMapping(TARGET_DOOR_STATE, TargetDoorStateEnum.class, true);
}

@Override
public void init() throws HomekitException {
super.init();
addService(new GarageDoorOpenerService(this));
}

@Override
public CompletableFuture<CurrentDoorStateEnum> getCurrentDoorState() {
return CompletableFuture.completedFuture(
getKeyFromMapping(CURRENT_DOOR_STATE, currentDoorStateMapping, CurrentDoorStateEnum.CLOSED));
}

@Override
public CompletableFuture<TargetDoorStateEnum> getTargetDoorState() {
return CompletableFuture.completedFuture(
getKeyFromMapping(TARGET_DOOR_STATE, targetDoorStateMapping, TargetDoorStateEnum.CLOSED));
}
var obstructionDetectedCharacteristic = getCharacteristic(ObstructionDetectedCharacteristic.class).orElseGet(
() -> new ObstructionDetectedCharacteristic(() -> CompletableFuture.completedFuture(false), (cb) -> {
}, () -> {
}));

@Override
public CompletableFuture<Boolean> getObstructionDetected() {
return CompletableFuture.completedFuture(obstructionReader.getValue());
}

@Override
public CompletableFuture<Void> setTargetDoorState(TargetDoorStateEnum targetDoorStateEnum) {
HomekitCharacteristicFactory.setValueFromEnum(getCharacteristic(TARGET_DOOR_STATE).get(), targetDoorStateEnum,
targetDoorStateMapping);
return CompletableFuture.completedFuture(null);
}

@Override
public void subscribeCurrentDoorState(HomekitCharacteristicChangeCallback callback) {
subscribe(CURRENT_DOOR_STATE, callback);
}

@Override
public void subscribeTargetDoorState(HomekitCharacteristicChangeCallback callback) {
subscribe(TARGET_DOOR_STATE, callback);
}

@Override
public void subscribeObstructionDetected(HomekitCharacteristicChangeCallback callback) {
subscribe(OBSTRUCTION_STATUS, callback);
}

@Override
public void unsubscribeCurrentDoorState() {
unsubscribe(CURRENT_DOOR_STATE);
}

@Override
public void unsubscribeTargetDoorState() {
unsubscribe(TARGET_DOOR_STATE);
}

@Override
public void unsubscribeObstructionDetected() {
unsubscribe(OBSTRUCTION_STATUS);
addService(new GarageDoorOpenerService(getCharacteristic(CurrentDoorStateCharacteristic.class).get(),
getCharacteristic(TargetDoorStateCharacteristic.class).get(), obstructionDetectedCharacteristic));
}
}

0 comments on commit 7303331

Please sign in to comment.