[homekit] allow group items of the correct type anywhere that type is needed (#13236)

this is a theme, and I've extracted a helper method and applied it to several
other locations as well

example, I have a double-sliding door, with two contact sensors
in the alarm system, defined as:

```
Group:Contact:AND(CLOSED,OPEN) DeckDoor_Contact "Deck Door [%s]" <door> (gExteriorDoors, gWarningVisibility_Contact, gDoor, lMainFloor, gInflux) { homekit="ContactSensor" [instance=2] }
Contact DeckNDoor_Contact "Deck Door North" <door> (gInflux, DeckDoor_Contact, gGreatContacts) { channel="dscalarm:zone:46c52f35:zone11:zone_status" }
Switch DeckNDoor_Tamper "Deck Door North Tamper [%s]" <warning> (gTamper, gWarningVisibility_Switch) { channel="dscalarm:zone:46c52f35:zone11:zone_tamper" }
Contact DeckSDoor_Contact "Deck Door South" <door> (gInflux, DeckDoor_Contact, gGreatContacts) { channel="dscalarm:zone:46c52f35:zone12:zone_status" }
Switch DeckSDoor_Tamper "Deck Door South Tamper [%s]" <warning> (gTamper, gWarningVisibility_Switch) { channel="dscalarm:zone:46c52f35:zone12:zone_tamper" }
```

This allows the Group:Contact to be used for the ContactSensor.

Signed-off-by: Cody Cutrer <cody@cutrer.us>
This commit is contained in:
Cody Cutrer 2022-09-26 10:58:59 -06:00 committed by GitHub
parent a3eafebbf3
commit e4fe6889d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 180 additions and 76 deletions

View File

@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.common.ThreadPoolManager; import org.openhab.core.common.ThreadPoolManager;
import org.openhab.core.items.GroupItem;
import org.openhab.core.items.Item; import org.openhab.core.items.Item;
import org.openhab.core.library.items.ColorItem; import org.openhab.core.library.items.ColorItem;
import org.openhab.core.library.items.DimmerItem; import org.openhab.core.library.items.DimmerItem;
@ -49,6 +50,7 @@ public class HomekitOHItemProxy {
private final Logger logger = LoggerFactory.getLogger(HomekitOHItemProxy.class); private final Logger logger = LoggerFactory.getLogger(HomekitOHItemProxy.class);
private static final int DEFAULT_DELAY = 50; // in ms private static final int DEFAULT_DELAY = 50; // in ms
private final Item item; private final Item item;
private final Item baseItem;
private final Map<HomekitCommandType, State> commandCache = new ConcurrentHashMap<>(); private final Map<HomekitCommandType, State> commandCache = new ConcurrentHashMap<>();
private final ScheduledExecutorService scheduler = ThreadPoolManager private final ScheduledExecutorService scheduler = ThreadPoolManager
.getScheduledPool(ThreadPoolManager.THREAD_POOL_NAME_COMMON); .getScheduledPool(ThreadPoolManager.THREAD_POOL_NAME_COMMON);
@ -57,8 +59,20 @@ public class HomekitOHItemProxy {
// delay, how long wait for further commands. in ms. // delay, how long wait for further commands. in ms.
private int delay = DEFAULT_DELAY; private int delay = DEFAULT_DELAY;
public static Item getBaseItem(Item item) {
if (item instanceof GroupItem) {
final GroupItem groupItem = (GroupItem) item;
final Item baseItem = groupItem.getBaseItem();
if (baseItem != null) {
return baseItem;
}
}
return item;
}
public HomekitOHItemProxy(Item item) { public HomekitOHItemProxy(Item item) {
this.item = item; this.item = item;
this.baseItem = getBaseItem(item);
} }
public Item getItem() { public Item getItem() {
@ -75,9 +89,9 @@ public class HomekitOHItemProxy {
@SuppressWarnings("null") @SuppressWarnings("null")
private void sendCommand() { private void sendCommand() {
if (!(item instanceof DimmerItem)) { if (!(baseItem instanceof DimmerItem)) {
// currently supports only DimmerItem and ColorItem (which extends DimmerItem) // currently supports only DimmerItem and ColorItem (which extends DimmerItem)
logger.debug("unexpected item type {}. Only DimmerItem and ColorItem are supported.", item); logger.debug("unexpected item type {}. Only DimmerItem and ColorItem are supported.", baseItem);
return; return;
} }
final OnOffType on = (OnOffType) commandCache.remove(ON_COMMAND); final OnOffType on = (OnOffType) commandCache.remove(ON_COMMAND);
@ -96,16 +110,20 @@ public class HomekitOHItemProxy {
|| ((dimmerMode == DIMMER_MODE_FILTER_ON_EXCEPT_BRIGHTNESS_100) && (currentOnState != OnOffType.ON) || ((dimmerMode == DIMMER_MODE_FILTER_ON_EXCEPT_BRIGHTNESS_100) && (currentOnState != OnOffType.ON)
&& ((brightness == null) || (brightness.intValue() == 100)))) { && ((brightness == null) || (brightness.intValue() == 100)))) {
logger.trace("send OnOff command for item {} with value {}", item, on); logger.trace("send OnOff command for item {} with value {}", item, on);
((DimmerItem) item).send(on); if (item instanceof GroupItem) {
((GroupItem) item).send(on);
} else {
((DimmerItem) item).send(on);
}
} }
} }
// if hue or saturation present, send an HSBType state update. no filter applied for HUE & Saturation // if hue or saturation present, send an HSBType state update. no filter applied for HUE & Saturation
if ((hue != null) || (saturation != null)) { if ((hue != null) || (saturation != null)) {
if (item instanceof ColorItem) { if (baseItem instanceof ColorItem) {
sendHSBCommand((ColorItem) item, hue, saturation, brightness); sendHSBCommand((ColorItem) item, hue, saturation, brightness);
} }
} else if ((brightness != null) && (item instanceof DimmerItem)) { } else if ((brightness != null) && (baseItem instanceof DimmerItem)) {
// sends brightness: // sends brightness:
// - DIMMER_MODE_NORMAL // - DIMMER_MODE_NORMAL
// - DIMMER_MODE_FILTER_ON // - DIMMER_MODE_FILTER_ON
@ -116,6 +134,8 @@ public class HomekitOHItemProxy {
logger.trace("send Brightness command for item {} with value {}", item, brightness); logger.trace("send Brightness command for item {} with value {}", item, brightness);
if (item instanceof ColorItem) { if (item instanceof ColorItem) {
sendHSBCommand((ColorItem) item, hue, saturation, brightness); sendHSBCommand((ColorItem) item, hue, saturation, brightness);
} else if (item instanceof GroupItem) {
((GroupItem) item).send(brightness);
} else { } else {
((DimmerItem) item).send(brightness); ((DimmerItem) item).send(brightness);
} }
@ -124,14 +144,19 @@ public class HomekitOHItemProxy {
commandCache.clear(); commandCache.clear();
} }
private void sendHSBCommand(ColorItem item, @Nullable DecimalType hue, @Nullable PercentType saturation, private void sendHSBCommand(Item item, @Nullable DecimalType hue, @Nullable PercentType saturation,
@Nullable PercentType brightness) { @Nullable PercentType brightness) {
final HSBType currentState = item.getState() instanceof UnDefType ? HSBType.BLACK : (HSBType) item.getState(); final HSBType currentState = item.getState() instanceof UnDefType ? HSBType.BLACK : (HSBType) item.getState();
// logic for ColorItem = combine hue, saturation and brightness update to one command // logic for ColorItem = combine hue, saturation and brightness update to one command
final DecimalType targetHue = hue != null ? hue : currentState.getHue(); final DecimalType targetHue = hue != null ? hue : currentState.getHue();
final PercentType targetSaturation = saturation != null ? saturation : currentState.getSaturation(); final PercentType targetSaturation = saturation != null ? saturation : currentState.getSaturation();
final PercentType targetBrightness = brightness != null ? brightness : currentState.getBrightness(); final PercentType targetBrightness = brightness != null ? brightness : currentState.getBrightness();
item.send(new HSBType(targetHue, targetSaturation, targetBrightness)); final HSBType command = new HSBType(targetHue, targetSaturation, targetBrightness);
if (item instanceof GroupItem) {
((GroupItem) item).send(command);
} else {
((ColorItem) item).send(command);
}
logger.trace("send HSB command for item {} with following values hue={} saturation={} brightness={}", item, logger.trace("send HSB command for item {} with following values hue={} saturation={} brightness={}", item,
targetHue, targetSaturation, targetBrightness); targetHue, targetSaturation, targetBrightness);
} }
@ -141,7 +166,7 @@ public class HomekitOHItemProxy {
logger.trace("add command to command cache: item {}, command type {}, command state {}. cache state after: {}", logger.trace("add command to command cache: item {}, command type {}, command state {}. cache state after: {}",
this, commandType, state, commandCache); this, commandType, state, commandCache);
// if cache has already HUE+SATURATION or BRIGHTNESS+ON then we don't expect any further relevant command // if cache has already HUE+SATURATION or BRIGHTNESS+ON then we don't expect any further relevant command
if (((item instanceof ColorItem) && commandCache.containsKey(HUE_COMMAND) if (((baseItem instanceof ColorItem) && commandCache.containsKey(HUE_COMMAND)
&& commandCache.containsKey(SATURATION_COMMAND)) && commandCache.containsKey(SATURATION_COMMAND))
|| (commandCache.containsKey(BRIGHTNESS_COMMAND) && commandCache.containsKey(ON_COMMAND))) { || (commandCache.containsKey(BRIGHTNESS_COMMAND) && commandCache.containsKey(ON_COMMAND))) {
if (future != null) { if (future != null) {

View File

@ -22,6 +22,15 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.items.GroupItem; import org.openhab.core.items.GroupItem;
import org.openhab.core.items.Item; import org.openhab.core.items.Item;
import org.openhab.core.library.items.DimmerItem;
import org.openhab.core.library.items.NumberItem;
import org.openhab.core.library.items.RollershutterItem;
import org.openhab.core.library.items.StringItem;
import org.openhab.core.library.items.SwitchItem;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.PercentType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.types.State; import org.openhab.core.types.State;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -137,6 +146,13 @@ public class HomekitTaggedItem {
return proxyItem.getItem(); return proxyItem.getItem();
} }
/**
* return the base item for a group, or the item itself, in order to do type checks
*/
public Item getBaseItem() {
return HomekitOHItemProxy.getBaseItem(proxyItem.getItem());
}
/** /**
* return proxy item which is used to group commands. * return proxy item which is used to group commands.
* *
@ -146,6 +162,78 @@ public class HomekitTaggedItem {
return proxyItem; return proxyItem;
} }
/**
* Send DecimalType command to a NumberItem (or a Group:Number)
*
* @param command
*/
public void send(DecimalType command) {
if (getItem() instanceof GroupItem && getBaseItem() instanceof NumberItem) {
((GroupItem) getItem()).send(command);
return;
} else if (getItem() instanceof NumberItem) {
((NumberItem) getItem()).send(command);
return;
}
logger.warn("Received DecimalType command for item {} that doesn't support it. This is probably a bug.",
getName());
}
/**
* Send OnOffType command to a SwitchItem (or a Group:Switch)
*
* @param command
*/
public void send(OnOffType command) {
if (getItem() instanceof GroupItem && getBaseItem() instanceof SwitchItem) {
((GroupItem) getItem()).send(command);
return;
} else if (getItem() instanceof SwitchItem) {
((SwitchItem) getItem()).send(command);
return;
}
logger.warn("Received OnOffType command for item {} that doesn't support it. This is probably a bug.",
getName());
}
/**
* Send PercentType command to a DimmerItem or RollershutterItem (or a Group:Dimmer/Group:Rollershutter)
*
* @param command
*/
public void send(PercentType command) {
if (getItem() instanceof GroupItem
&& (getBaseItem() instanceof DimmerItem || getBaseItem() instanceof RollershutterItem)) {
((GroupItem) getItem()).send(command);
return;
} else if (getItem() instanceof DimmerItem) {
((DimmerItem) getItem()).send(command);
return;
} else if (getItem() instanceof RollershutterItem) {
((RollershutterItem) getItem()).send(command);
return;
}
logger.warn("Received PercentType command for item {} that doesn't support it. This is probably a bug.",
getName());
}
/**
* Send StringType command to a StringItem (or a Group:String)
*
* @param command
*/
public void send(StringType command) {
if (getItem() instanceof GroupItem && getBaseItem() instanceof StringItem) {
((GroupItem) getItem()).send(command);
return;
} else if (getItem() instanceof StringItem) {
((StringItem) getItem()).send(command);
return;
}
logger.warn("Received StringType command for item {} that doesn't support it. This is probably a bug.",
getName());
}
/** /**
* send openHAB item command via proxy item, which allows to group commands. * send openHAB item command via proxy item, which allows to group commands.
* e.g. sendCommandProxy(hue), sendCommandProxy(brightness) would lead to one openHAB command that updates hue and * e.g. sendCommandProxy(hue), sendCommandProxy(brightness) would lead to one openHAB command that updates hue and

View File

@ -163,14 +163,7 @@ abstract class AbstractHomekitPositionAccessoryImpl extends AbstractHomekitAcces
final Optional<HomekitTaggedItem> taggedItem = getCharacteristic(type); final Optional<HomekitTaggedItem> taggedItem = getCharacteristic(type);
if (taggedItem.isPresent()) { if (taggedItem.isPresent()) {
final Item item = taggedItem.get().getItem(); final Item item = taggedItem.get().getItem();
Item baseItem = item; final Item baseItem = taggedItem.get().getBaseItem();
// Check the type of the base item for a group item
if (item instanceof GroupItem) {
baseItem = ((GroupItem) item).getBaseItem();
if (baseItem == null) {
baseItem = item;
}
}
if (baseItem instanceof RollershutterItem || baseItem instanceof DimmerItem) { if (baseItem instanceof RollershutterItem || baseItem instanceof DimmerItem) {
value = item.getStateAs(PercentType.class); value = item.getStateAs(PercentType.class);
} else { } else {

View File

@ -22,6 +22,7 @@ import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType; import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.library.types.StringType; import org.openhab.core.library.types.StringType;
import org.openhab.core.types.State; import org.openhab.core.types.State;
import org.openhab.io.homekit.internal.HomekitOHItemProxy;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -48,7 +49,9 @@ public class BooleanItemReader {
this.item = item; this.item = item;
this.trueOnOffValue = trueOnOffValue; this.trueOnOffValue = trueOnOffValue;
this.trueOpenClosedValue = trueOpenClosedValue; this.trueOpenClosedValue = trueOpenClosedValue;
if (!(item instanceof SwitchItem) && !(item instanceof ContactItem) && !(item instanceof StringItem)) { final Item baseItem = HomekitOHItemProxy.getBaseItem(item);
if (!(baseItem instanceof SwitchItem) && !(baseItem instanceof ContactItem)
&& !(baseItem instanceof StringItem)) {
logger.warn("Item {} is a {} instead of the expected SwitchItem, ContactItem or StringItem", item.getName(), logger.warn("Item {} is a {} instead of the expected SwitchItem, ContactItem or StringItem", item.getName(),
item.getClass().getName()); item.getClass().getName());
} }

View File

@ -29,7 +29,6 @@ import javax.measure.Unit;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.items.GenericItem; import org.openhab.core.items.GenericItem;
import org.openhab.core.items.Item;
import org.openhab.core.library.items.ColorItem; import org.openhab.core.library.items.ColorItem;
import org.openhab.core.library.items.DimmerItem; import org.openhab.core.library.items.DimmerItem;
import org.openhab.core.library.items.NumberItem; import org.openhab.core.library.items.NumberItem;
@ -188,8 +187,8 @@ public class HomekitCharacteristicFactory {
if (optional.containsKey(type)) { if (optional.containsKey(type)) {
return optional.get(type).apply(item, updater); return optional.get(type).apply(item, updater);
} }
logger.warn("Unsupported optional characteristic. Accessory type {}, characteristic type {}", logger.warn("Unsupported optional characteristic from item {}. Accessory type {}, characteristic type {}",
item.getAccessoryType(), type.getTag()); item.getName(), item.getAccessoryType(), type.getTag());
throw new HomekitException( throw new HomekitException(
"Unsupported optional characteristic. Characteristic type \"" + type.getTag() + "\""); "Unsupported optional characteristic. Characteristic type \"" + type.getTag() + "\"");
} }
@ -225,20 +224,20 @@ public class HomekitCharacteristicFactory {
private static void setValueFromEnum(HomekitTaggedItem taggedItem, CharacteristicEnum value, private static void setValueFromEnum(HomekitTaggedItem taggedItem, CharacteristicEnum value,
CharacteristicEnum offEnum, CharacteristicEnum onEnum) { CharacteristicEnum offEnum, CharacteristicEnum onEnum) {
if (taggedItem.getItem() instanceof SwitchItem) { if (taggedItem.getBaseItem() instanceof SwitchItem) {
if (value.equals(offEnum)) { if (value.equals(offEnum)) {
((SwitchItem) taggedItem.getItem()).send(taggedItem.isInverted() ? OnOffType.ON : OnOffType.OFF); taggedItem.send(taggedItem.isInverted() ? OnOffType.ON : OnOffType.OFF);
} else if (value.equals(onEnum)) { } else if (value.equals(onEnum)) {
((SwitchItem) taggedItem.getItem()).send(taggedItem.isInverted() ? OnOffType.OFF : OnOffType.ON); taggedItem.send(taggedItem.isInverted() ? OnOffType.OFF : OnOffType.ON);
} else { } else {
logger.warn("Enum value {} is not supported. Only following values are supported: {},{}", value, logger.warn("Enum value {} is not supported for {}. Only following values are supported: {},{}", value,
offEnum, onEnum); taggedItem.getName(), offEnum, onEnum);
} }
} else if (taggedItem.getItem() instanceof NumberItem) { } else if (taggedItem.getBaseItem() instanceof NumberItem) {
((NumberItem) taggedItem.getItem()).send(new DecimalType(value.getCode())); taggedItem.send(new DecimalType(value.getCode()));
} else { } else {
logger.warn("Item type {} is not supported. Only Switch and Number item types are supported.", logger.warn("Item {} of type {} is not supported. Only Switch and Number item types are supported.",
taggedItem.getItem().getType()); taggedItem.getName(), taggedItem.getBaseItem().getType());
} }
} }
@ -311,38 +310,38 @@ public class HomekitCharacteristicFactory {
private static ExceptionalConsumer<Integer> setIntConsumer(HomekitTaggedItem taggedItem) { private static ExceptionalConsumer<Integer> setIntConsumer(HomekitTaggedItem taggedItem) {
return (value) -> { return (value) -> {
if (taggedItem.getItem() instanceof NumberItem) { if (taggedItem.getBaseItem() instanceof NumberItem) {
((NumberItem) taggedItem.getItem()).send(new DecimalType(value)); taggedItem.send(new DecimalType(value));
} else { } else {
logger.warn("Item type {} is not supported for {}. Only NumberItem is supported.", logger.warn("Item type {} is not supported for {}. Only NumberItem is supported.",
taggedItem.getItem().getType(), taggedItem.getName()); taggedItem.getBaseItem().getType(), taggedItem.getName());
} }
}; };
} }
private static ExceptionalConsumer<Integer> setPercentConsumer(HomekitTaggedItem taggedItem) { private static ExceptionalConsumer<Integer> setPercentConsumer(HomekitTaggedItem taggedItem) {
return (value) -> { return (value) -> {
if (taggedItem.getItem() instanceof NumberItem) { if (taggedItem.getBaseItem() instanceof NumberItem) {
((NumberItem) taggedItem.getItem()).send(new DecimalType(value)); taggedItem.send(new DecimalType(value));
} else if (taggedItem.getItem() instanceof DimmerItem) { } else if (taggedItem.getBaseItem() instanceof DimmerItem) {
((DimmerItem) taggedItem.getItem()).send(new PercentType(value)); taggedItem.send(new PercentType(value));
} else { } else {
logger.warn("Item type {} is not supported for {}. Only DimmerItem and NumberItem are supported.", logger.warn("Item type {} is not supported for {}. Only DimmerItem and NumberItem are supported.",
taggedItem.getItem().getType(), taggedItem.getName()); taggedItem.getBaseItem().getType(), taggedItem.getName());
} }
}; };
} }
private static ExceptionalConsumer<Integer> setAngleConsumer(HomekitTaggedItem taggedItem) { private static ExceptionalConsumer<Integer> setAngleConsumer(HomekitTaggedItem taggedItem) {
return (value) -> { return (value) -> {
if (taggedItem.getItem() instanceof NumberItem) { if (taggedItem.getBaseItem() instanceof NumberItem) {
((NumberItem) taggedItem.getItem()).send(new DecimalType(value)); taggedItem.send(new DecimalType(value));
} else if (taggedItem.getItem() instanceof DimmerItem) { } else if (taggedItem.getBaseItem() instanceof DimmerItem) {
value = (int) (value * 50.0 / 90.0 + 50.0); value = (int) (value * 50.0 / 90.0 + 50.0);
((DimmerItem) taggedItem.getItem()).send(new PercentType(value)); taggedItem.send(new PercentType(value));
} else { } else {
logger.warn("Item type {} is not supported for {}. Only DimmerItem and NumberItem are supported.", logger.warn("Item type {} is not supported for {}. Only DimmerItem and NumberItem are supported.",
taggedItem.getItem().getType(), taggedItem.getName()); taggedItem.getBaseItem().getType(), taggedItem.getName());
} }
}; };
} }
@ -363,13 +362,13 @@ public class HomekitCharacteristicFactory {
private static ExceptionalConsumer<Double> setDoubleConsumer(HomekitTaggedItem taggedItem) { private static ExceptionalConsumer<Double> setDoubleConsumer(HomekitTaggedItem taggedItem) {
return (value) -> { return (value) -> {
if (taggedItem.getItem() instanceof NumberItem) { if (taggedItem.getBaseItem() instanceof NumberItem) {
((NumberItem) taggedItem.getItem()).send(new DecimalType(value.doubleValue())); taggedItem.send(new DecimalType(value.doubleValue()));
} else if (taggedItem.getItem() instanceof DimmerItem) { } else if (taggedItem.getBaseItem() instanceof DimmerItem) {
((DimmerItem) taggedItem.getItem()).send(new PercentType(value.intValue())); taggedItem.send(new PercentType(value.intValue()));
} else { } else {
logger.warn("Item type {} is not supported for {}. Only Number and Dimmer type are supported.", logger.warn("Item type {} is not supported for {}. Only Number and Dimmer type are supported.",
taggedItem.getItem().getType(), taggedItem.getName()); taggedItem.getBaseItem().getType(), taggedItem.getName());
} }
}; };
} }
@ -384,11 +383,11 @@ public class HomekitCharacteristicFactory {
private static ExceptionalConsumer<Double> setTemperatureConsumer(HomekitTaggedItem taggedItem) { private static ExceptionalConsumer<Double> setTemperatureConsumer(HomekitTaggedItem taggedItem) {
return (value) -> { return (value) -> {
if (taggedItem.getItem() instanceof NumberItem) { if (taggedItem.getBaseItem() instanceof NumberItem) {
((NumberItem) taggedItem.getItem()).send(new DecimalType(convertFromCelsius(value))); taggedItem.send(new DecimalType(convertFromCelsius(value)));
} else { } else {
logger.warn("Item type {} is not supported for {}. Only Number type is supported.", logger.warn("Item type {} is not supported for {}. Only Number type is supported.",
taggedItem.getItem().getType(), taggedItem.getName()); taggedItem.getBaseItem().getType(), taggedItem.getName());
} }
}; };
} }
@ -552,11 +551,11 @@ public class HomekitCharacteristicFactory {
} }
return CompletableFuture.completedFuture(value); return CompletableFuture.completedFuture(value);
}, (hue) -> { }, (hue) -> {
if (taggedItem.getItem() instanceof ColorItem) { if (taggedItem.getBaseItem() instanceof ColorItem) {
taggedItem.sendCommandProxy(HomekitCommandType.HUE_COMMAND, new DecimalType(hue)); taggedItem.sendCommandProxy(HomekitCommandType.HUE_COMMAND, new DecimalType(hue));
} else { } else {
logger.warn("Item type {} is not supported for {}. Only Color type is supported.", logger.warn("Item type {} is not supported for {}. Only Color type is supported.",
taggedItem.getItem().getType(), taggedItem.getName()); taggedItem.getBaseItem().getType(), taggedItem.getName());
} }
}, getSubscriber(taggedItem, HUE, updater), getUnsubscriber(taggedItem, HUE, updater)); }, getSubscriber(taggedItem, HUE, updater), getUnsubscriber(taggedItem, HUE, updater));
} }
@ -573,12 +572,11 @@ public class HomekitCharacteristicFactory {
} }
return CompletableFuture.completedFuture(value); return CompletableFuture.completedFuture(value);
}, (brightness) -> { }, (brightness) -> {
final Item item = taggedItem.getItem(); if (taggedItem.getBaseItem() instanceof DimmerItem) {
if (item instanceof DimmerItem) {
taggedItem.sendCommandProxy(HomekitCommandType.BRIGHTNESS_COMMAND, new PercentType(brightness)); taggedItem.sendCommandProxy(HomekitCommandType.BRIGHTNESS_COMMAND, new PercentType(brightness));
} else { } else {
logger.warn("Item type {} is not supported for {}. Only ColorItem and DimmerItem are supported.", logger.warn("Item type {} is not supported for {}. Only ColorItem and DimmerItem are supported.",
item.getType(), taggedItem.getName()); taggedItem.getBaseItem().getType(), taggedItem.getName());
} }
}, getSubscriber(taggedItem, BRIGHTNESS, updater), getUnsubscriber(taggedItem, BRIGHTNESS, updater)); }, getSubscriber(taggedItem, BRIGHTNESS, updater), getUnsubscriber(taggedItem, BRIGHTNESS, updater));
} }
@ -595,12 +593,12 @@ public class HomekitCharacteristicFactory {
} }
return CompletableFuture.completedFuture(value); return CompletableFuture.completedFuture(value);
}, (saturation) -> { }, (saturation) -> {
if (taggedItem.getItem() instanceof ColorItem) { if (taggedItem.getBaseItem() instanceof ColorItem) {
taggedItem.sendCommandProxy(HomekitCommandType.SATURATION_COMMAND, taggedItem.sendCommandProxy(HomekitCommandType.SATURATION_COMMAND,
new PercentType(saturation.intValue())); new PercentType(saturation.intValue()));
} else { } else {
logger.warn("Item type {} is not supported for {}. Only Color type is supported.", logger.warn("Item type {} is not supported for {}. Only Color type is supported.",
taggedItem.getItem().getType(), taggedItem.getName()); taggedItem.getBaseItem().getType(), taggedItem.getName());
} }
}, getSubscriber(taggedItem, SATURATION, updater), getUnsubscriber(taggedItem, SATURATION, updater)); }, getSubscriber(taggedItem, SATURATION, updater), getUnsubscriber(taggedItem, SATURATION, updater));
} }

View File

@ -26,6 +26,7 @@ import org.openhab.core.library.items.SwitchItem;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.StringType; import org.openhab.core.library.types.StringType;
import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater;
import org.openhab.io.homekit.internal.HomekitOHItemProxy;
import org.openhab.io.homekit.internal.HomekitSettings; import org.openhab.io.homekit.internal.HomekitSettings;
import org.openhab.io.homekit.internal.HomekitTaggedItem; import org.openhab.io.homekit.internal.HomekitTaggedItem;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -100,9 +101,10 @@ public class HomekitGarageDoorOpenerImpl extends AbstractHomekitAccessoryImpl im
} }
TargetDoorStateEnum mode; TargetDoorStateEnum mode;
if (item instanceof SwitchItem) { final Item baseItem = HomekitOHItemProxy.getBaseItem(item);
if (baseItem instanceof SwitchItem) {
mode = item.getState() == OnOffType.ON ? TargetDoorStateEnum.OPEN : TargetDoorStateEnum.CLOSED; mode = item.getState() == OnOffType.ON ? TargetDoorStateEnum.OPEN : TargetDoorStateEnum.CLOSED;
} else if (item instanceof StringItem) { } else if (baseItem instanceof StringItem) {
final HomekitSettings settings = getSettings(); final HomekitSettings settings = getSettings();
final String stringValue = item.getState().toString(); final String stringValue = item.getState().toString();
if (stringValue.equalsIgnoreCase(settings.doorTargetStateClosed)) { if (stringValue.equalsIgnoreCase(settings.doorTargetStateClosed)) {
@ -116,7 +118,7 @@ public class HomekitGarageDoorOpenerImpl extends AbstractHomekitAccessoryImpl im
mode = TargetDoorStateEnum.CLOSED; mode = TargetDoorStateEnum.CLOSED;
} }
} else { } else {
logger.warn("Unsupported item type {} for {}. Only Switch and String are supported", item.getType(), logger.warn("Unsupported item type {} for {}. Only Switch and String are supported", baseItem.getType(),
item.getName()); item.getName());
mode = TargetDoorStateEnum.CLOSED; mode = TargetDoorStateEnum.CLOSED;
} }
@ -131,24 +133,24 @@ public class HomekitGarageDoorOpenerImpl extends AbstractHomekitAccessoryImpl im
@Override @Override
public CompletableFuture<Void> setTargetDoorState(TargetDoorStateEnum targetDoorStateEnum) { public CompletableFuture<Void> setTargetDoorState(TargetDoorStateEnum targetDoorStateEnum) {
final Optional<HomekitTaggedItem> characteristic = getCharacteristic(TARGET_DOOR_STATE); final Optional<HomekitTaggedItem> characteristic = getCharacteristic(TARGET_DOOR_STATE);
Item item; final HomekitTaggedItem taggedItem;
if (characteristic.isPresent()) { if (characteristic.isPresent()) {
item = characteristic.get().getItem(); taggedItem = characteristic.get();
} else { } else {
logger.warn("Missing mandatory characteristic {}", TARGET_DOOR_STATE); logger.warn("Missing mandatory characteristic {}", TARGET_DOOR_STATE);
return CompletableFuture.completedFuture(null); return CompletableFuture.completedFuture(null);
} }
if (item instanceof SwitchItem) { if (taggedItem.getBaseItem() instanceof SwitchItem) {
((SwitchItem) item).send(OnOffType.from(targetDoorStateEnum == TargetDoorStateEnum.OPEN)); taggedItem.send(OnOffType.from(targetDoorStateEnum == TargetDoorStateEnum.OPEN));
} else if (item instanceof StringItem) { } else if (taggedItem.getBaseItem() instanceof StringItem) {
final HomekitSettings settings = getSettings(); final HomekitSettings settings = getSettings();
((StringItem) item) taggedItem
.send(new StringType(targetDoorStateEnum == TargetDoorStateEnum.OPEN ? settings.doorTargetStateOpen .send(new StringType(targetDoorStateEnum == TargetDoorStateEnum.OPEN ? settings.doorTargetStateOpen
: settings.doorTargetStateClosed)); : settings.doorTargetStateClosed));
} else { } else {
logger.warn("Unsupported item type {} for {}. Only Switch and String are supported", item.getType(), logger.warn("Unsupported item type {} for {}. Only Switch and String are supported",
item.getName()); taggedItem.getBaseItem().getType(), taggedItem.getName());
} }
return CompletableFuture.completedFuture(null); return CompletableFuture.completedFuture(null);
} }

View File

@ -15,8 +15,6 @@ package org.openhab.io.homekit.internal.accessories;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import org.openhab.core.items.GenericItem;
import org.openhab.core.items.GroupItem;
import org.openhab.core.library.items.DimmerItem; import org.openhab.core.library.items.DimmerItem;
import org.openhab.core.library.items.SwitchItem; import org.openhab.core.library.items.SwitchItem;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
@ -53,13 +51,10 @@ class HomekitLightbulbImpl extends AbstractHomekitAccessoryImpl implements Light
public CompletableFuture<Void> setLightbulbPowerState(boolean value) { public CompletableFuture<Void> setLightbulbPowerState(boolean value) {
getCharacteristic(HomekitCharacteristicType.ON_STATE).ifPresent(tItem -> { getCharacteristic(HomekitCharacteristicType.ON_STATE).ifPresent(tItem -> {
final OnOffType onOffState = OnOffType.from(value); final OnOffType onOffState = OnOffType.from(value);
final GenericItem item = (GenericItem) tItem.getItem(); if (tItem.getBaseItem() instanceof DimmerItem) {
if (item instanceof DimmerItem) {
tItem.sendCommandProxy(HomekitCommandType.ON_COMMAND, onOffState); tItem.sendCommandProxy(HomekitCommandType.ON_COMMAND, onOffState);
} else if (item instanceof SwitchItem) { } else if (tItem.getBaseItem() instanceof SwitchItem) {
((SwitchItem) item).send(onOffState); tItem.send(onOffState);
} else if (item instanceof GroupItem) {
((GroupItem) item).send(onOffState);
} }
}); });
return CompletableFuture.completedFuture(null); return CompletableFuture.completedFuture(null);