Skip to content

Commit

Permalink
Adding ColorfulLightbulb Homekit Characteristic (openhab#1323)
Browse files Browse the repository at this point in the history
* Getting rid of the Unrecognized heating cooling target mode: NULL warning
* Added support for colorful lightbulbs in HomeKit binding

Signed-off-by: Felix Rotthowe <[email protected]> (github: planbnet)
  • Loading branch information
planbnet authored and kaikreuzer committed Nov 13, 2016
1 parent 52652cf commit db7e038
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 5 deletions.
2 changes: 1 addition & 1 deletion addons/io/org.openhab.io.homekit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ A full list of supported accessory types can be found in the table below.
<td>Lighting</td>
<td>&nbsp;</td>
<td>Switch, Dimmer, Color</td>
<td>A lightbulb, either switchable or dimmable</td>
<td>A lightbulb, switchable, dimmable or rgb</td>
</tr>
<tr>
<td>Switchable</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, HomekitDeviceType> tagMap = new HashMap<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
@@ -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<ColorItem>
implements ColorfulLightbulb, DimmableLightbulb {

public HomekitColorfulLightbulbImpl(HomekitTaggedItem taggedItem, ItemRegistry itemRegistry,
HomekitAccessoryUpdater updater) {
super(taggedItem, itemRegistry, updater, ColorItem.class);
}

@Override
public CompletableFuture<Double> 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<Double> 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<Integer> 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<Void> 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<Void> 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<Void> 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");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -35,8 +36,13 @@ public HomekitDimmableLightbulbImpl(HomekitTaggedItem taggedItem, ItemRegistry i

@Override
public CompletableFuture<Integer> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ public CompletableFuture<ThermostatMode> 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.");
Expand Down

0 comments on commit db7e038

Please sign in to comment.