diff --git a/addons/io/org.openhab.io.homekit/README.md b/addons/io/org.openhab.io.homekit/README.md index 67d746c94ba..0b233cfb1fc 100644 --- a/addons/io/org.openhab.io.homekit/README.md +++ b/addons/io/org.openhab.io.homekit/README.md @@ -39,7 +39,7 @@ A full list of supported accessory types can be found in the table below. Lighting   Switch, Dimmer, Color - A lightbulb, either switchable or dimmable + A lightbulb, switchable, dimmable or rgb Switchable diff --git a/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitDeviceType.java b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitDeviceType.java index a328301dcd7..be7b208dfec 100644 --- a/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitDeviceType.java +++ b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitDeviceType.java @@ -24,7 +24,8 @@ public enum HomekitDeviceType { LIGHTBULB("Lighting"), SWITCH("Switchable"), TEMPERATURE_SENSOR("CurrentTemperature"), - THERMOSTAT("Thermostat"); + THERMOSTAT("Thermostat"), + COLORFUL_LIGHTBULB("ColorfulLighting"); private static final Map tagMap = new HashMap<>(); diff --git a/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitTaggedItem.java b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitTaggedItem.java index 46dde3490f4..3ecde4fdc7d 100644 --- a/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitTaggedItem.java +++ b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitTaggedItem.java @@ -14,6 +14,7 @@ import org.apache.commons.lang.builder.HashCodeBuilder; import org.eclipse.smarthome.core.items.Item; import org.eclipse.smarthome.core.items.ItemRegistry; +import org.eclipse.smarthome.core.library.items.ColorItem; import org.eclipse.smarthome.core.library.items.DimmerItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,9 +37,13 @@ public class HomekitTaggedItem { public HomekitTaggedItem(Item item, ItemRegistry itemRegistry) { this.item = item; for (String tag : item.getTags()) { - if (item instanceof DimmerItem) { + + if (item instanceof ColorItem) { + tag = "Colorful" + tag; + } else if (item instanceof DimmerItem) { tag = "Dimmable" + tag; } + /* * Is the item part of a tagged group AND does it have a matching CharacteristicType ? * This matches items with tags that require a parent group like the "TargetTemperature" in diff --git a/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitAccessoryFactory.java b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitAccessoryFactory.java index afbcd2296b7..32964aa85dc 100644 --- a/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitAccessoryFactory.java +++ b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitAccessoryFactory.java @@ -31,6 +31,9 @@ public static HomekitAccessory create(HomekitTaggedItem taggedItem, ItemRegistry case DIMMABLE_LIGHTBULB: return new HomekitDimmableLightbulbImpl(taggedItem, itemRegistry, updater); + case COLORFUL_LIGHTBULB: + return new HomekitColorfulLightbulbImpl(taggedItem, itemRegistry, updater); + case THERMOSTAT: return new HomekitThermostatImpl(taggedItem, itemRegistry, updater, settings); diff --git a/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitColorfulLightbulbImpl.java b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitColorfulLightbulbImpl.java new file mode 100644 index 00000000000..37511976654 --- /dev/null +++ b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitColorfulLightbulbImpl.java @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2014-2016 by the respective copyright holders. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.openhab.io.homekit.internal.accessories; + +import java.util.concurrent.CompletableFuture; + +import org.eclipse.smarthome.core.items.ItemRegistry; +import org.eclipse.smarthome.core.library.items.ColorItem; +import org.eclipse.smarthome.core.library.types.DecimalType; +import org.eclipse.smarthome.core.library.types.HSBType; +import org.eclipse.smarthome.core.library.types.PercentType; +import org.eclipse.smarthome.core.types.State; +import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; +import org.openhab.io.homekit.internal.HomekitTaggedItem; + +import com.beowulfe.hap.HomekitCharacteristicChangeCallback; +import com.beowulfe.hap.accessories.ColorfulLightbulb; +import com.beowulfe.hap.accessories.DimmableLightbulb; + +/** + * Implements ColorfulLightBulb using an Item that provides a On/Off and color state + * + * @author Felix Rotthowe + */ +class HomekitColorfulLightbulbImpl extends AbstractHomekitLightbulbImpl + implements ColorfulLightbulb, DimmableLightbulb { + + public HomekitColorfulLightbulbImpl(HomekitTaggedItem taggedItem, ItemRegistry itemRegistry, + HomekitAccessoryUpdater updater) { + super(taggedItem, itemRegistry, updater, ColorItem.class); + } + + @Override + public CompletableFuture getHue() { + State state = getItem().getStateAs(HSBType.class); + if (state instanceof HSBType) { + HSBType hsb = (HSBType) state; + return CompletableFuture.completedFuture(hsb.getHue().doubleValue()); + } else { + return null; + } + } + + @Override + public CompletableFuture getSaturation() { + State state = getItem().getStateAs(HSBType.class); + if (state instanceof HSBType) { + HSBType hsb = (HSBType) state; + return CompletableFuture.completedFuture(hsb.getSaturation().doubleValue()); + } else { + return null; + } + } + + @Override + public CompletableFuture getBrightness() { + State state = getItem().getStateAs(PercentType.class); + if (state instanceof PercentType) { + PercentType brightness = (PercentType) state; + return CompletableFuture.completedFuture(brightness.intValue()); + } else { + return CompletableFuture.completedFuture(null); + } + } + + @Override + public CompletableFuture setHue(Double value) throws Exception { + if (value == null) { + value = 0.0; + } + State state = getItem().getStateAs(HSBType.class); + if (state instanceof HSBType) { + HSBType hsb = (HSBType) state; + HSBType newState = new HSBType(new DecimalType(value), hsb.getSaturation(), hsb.getBrightness()); + ((ColorItem) getItem()).send(newState); + return CompletableFuture.completedFuture(null); + } else { + // state is undefined (light is not connected) + return CompletableFuture.completedFuture(null); + } + } + + @Override + public CompletableFuture setSaturation(Double value) throws Exception { + if (value == null) { + value = 0.0; + } + State state = getItem().getStateAs(HSBType.class); + if (state instanceof HSBType) { + HSBType hsb = (HSBType) state; + HSBType newState = new HSBType(hsb.getHue(), new PercentType(value.intValue()), hsb.getBrightness()); + ((ColorItem) getItem()).send(newState); + return CompletableFuture.completedFuture(null); + } else { + // state is undefined (light is not connected) + return CompletableFuture.completedFuture(null); + } + } + + @Override + public CompletableFuture setBrightness(Integer value) throws Exception { + if (value == null) { + value = 0; + } + State state = getItem().getStateAs(HSBType.class); + if (state instanceof HSBType) { + HSBType hsb = (HSBType) state; + HSBType newState = new HSBType(hsb.getHue(), hsb.getSaturation(), new PercentType(value)); + ((ColorItem) getItem()).send(newState); + return CompletableFuture.completedFuture(null); + } else { + // state is undefined (light is not connected) + return CompletableFuture.completedFuture(null); + } + } + + @Override + public void subscribeHue(HomekitCharacteristicChangeCallback callback) { + getUpdater().subscribe(getItem(), "hue", callback); + } + + @Override + public void subscribeSaturation(HomekitCharacteristicChangeCallback callback) { + getUpdater().subscribe(getItem(), "saturation", callback); + } + + @Override + public void subscribeBrightness(HomekitCharacteristicChangeCallback callback) { + getUpdater().subscribe(getItem(), "brightness", callback); + } + + @Override + public void unsubscribeHue() { + getUpdater().unsubscribe(getItem(), "hue"); + } + + @Override + public void unsubscribeSaturation() { + getUpdater().unsubscribe(getItem(), "saturation"); + } + + @Override + public void unsubscribeBrightness() { + getUpdater().unsubscribe(getItem(), "brightness"); + } + +} diff --git a/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitDimmableLightbulbImpl.java b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitDimmableLightbulbImpl.java index 9fcde56be89..302c43dd8a0 100644 --- a/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitDimmableLightbulbImpl.java +++ b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitDimmableLightbulbImpl.java @@ -15,6 +15,7 @@ import org.eclipse.smarthome.core.items.ItemRegistry; import org.eclipse.smarthome.core.library.items.DimmerItem; import org.eclipse.smarthome.core.library.types.PercentType; +import org.eclipse.smarthome.core.types.State; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitTaggedItem; @@ -35,8 +36,13 @@ public HomekitDimmableLightbulbImpl(HomekitTaggedItem taggedItem, ItemRegistry i @Override public CompletableFuture getBrightness() { - PercentType state = (PercentType) getItem().getStateAs(PercentType.class); - return CompletableFuture.completedFuture(state.intValue()); + State state = getItem().getStateAs(PercentType.class); + if (state instanceof PercentType) { + PercentType brightness = (PercentType) state; + return CompletableFuture.completedFuture(brightness.intValue()); + } else { + return CompletableFuture.completedFuture(null); + } } @Override diff --git a/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitThermostatImpl.java b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitThermostatImpl.java index 11ebe56f1e6..33478275cba 100644 --- a/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitThermostatImpl.java +++ b/addons/io/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitThermostatImpl.java @@ -109,6 +109,9 @@ public CompletableFuture getCurrentMode() { mode = ThermostatMode.AUTO; } else if (stringValue.equals(settings.getThermostatOffMode())) { mode = ThermostatMode.OFF; + } else if ( stringValue.equals("UNDEF") || stringValue.equals("NULL") ) { + logger.debug("Heating cooling target mode not available. Relaying value of OFF to Homekit"); + mode = ThermostatMode.OFF; } else { logger.error("Unrecognized heating cooling target mode: " + stringValue + ". Expected cool, heat, auto, or off strings in value.");