Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[homekit] Make GarageDoorOpener.ObstructionStatus optional #17137

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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));
}
}