/**
* Copyright (c) 2010-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.binding.dmx.internal.config;
import java.awt.Color;
import org.openhab.binding.dmx.DmxBindingProvider;
import org.openhab.binding.dmx.DmxService;
import org.openhab.binding.dmx.internal.core.DmxUtil;
import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.IncreaseDecreaseType;
import org.openhab.core.library.types.PercentType;
import org.openhab.core.types.Command;
import org.openhab.model.item.binding.BindingConfigParseException;
/**
* DMX item configuration for openHab Color Items.
*
* @author Davy Vanherbergen
* @since 1.2.0
*/
public class DmxColorItem extends DmxDimmerItem {
private static int BRIGHTNESS_STEP_SIZE = 5;
private HSBType hsbState;
/**
* Create new color item using a given configuration string.
*
* @param itemName
* name of the item
* @param configString
* configuration string
* @param dmxBindingProvider
* binding provider which created the item
* @throws BindingConfigParseException
* if configuration string could not be parsed.
*/
public DmxColorItem(String itemName, String configString, DmxBindingProvider dmxBindingProvider)
throws BindingConfigParseException {
super(itemName, configString, dmxBindingProvider);
}
/**
* {@inheritDoc}
*/
@Override
public void processCommand(DmxService service, Command command) {
// process HSB command
if (command instanceof HSBType) {
HSBType hsbValue = (HSBType) command;
setHSBValue(service, hsbValue);
return;
}
// process increase/decrease
if (command instanceof IncreaseDecreaseType && !isRedefinedByCustomCommand(command)
&& !service.hasChannelActions(channels[0])) {
// rather than doing a linear fade on all channels, we fade only the
// V part of HSV to maintain the color during the fade
HSBType hsb = hsbState;
int brightness = 0;
IncreaseDecreaseType t = (IncreaseDecreaseType) command;
if (IncreaseDecreaseType.INCREASE.equals(t)) {
if (hsb == null) {
hsb = new HSBType(Color.WHITE);
}
for (int ch : channels) {
service.enableChannel(ch);
}
brightness = hsb.getBrightness().intValue();
brightness += BRIGHTNESS_STEP_SIZE;
if (brightness > 100) {
brightness = 100;
}
} else {
if (hsb == null) {
hsb = new HSBType(Color.BLACK);
}
brightness = hsb.getBrightness().intValue();
brightness -= BRIGHTNESS_STEP_SIZE;
if (brightness <= 0) {
brightness = 0;
}
}
HSBType newHsb = new HSBType(hsb.getHue(), hsb.getSaturation(), new PercentType(brightness));
setHSBValue(service, newHsb);
return;
}
// process percent command
if (command instanceof PercentType && !isRedefinedByCustomCommand(command)
&& !service.hasChannelActions(channels[0])) {
PercentType t = (PercentType) command;
HSBType hsb = hsbState;
if (hsb == null) {
hsb = new HSBType(Color.WHITE);
}
HSBType newHsb = new HSBType(hsb.getHue(), hsb.getSaturation(), t);
setHSBValue(service, newHsb);
return;
}
// process on/off, increase/decrease, percent type
super.processCommand(service, command);
}
private void setHSBValue(DmxService service, HSBType hsbValue) {
hsbState = hsbValue;
int valueLength = isRgbw() ? 4 : 3;
int[] values = new int[valueLength];
values[0] = DmxUtil.getByteFromPercentType(hsbValue.getRed());
values[1] = DmxUtil.getByteFromPercentType(hsbValue.getGreen());
values[2] = DmxUtil.getByteFromPercentType(hsbValue.getBlue());
if (isRgbw()) {
values[3] = DmxUtil.calculateWhite(values[0], values[1], values[3]);
}
int j = 0;
for (int c : channels) {
service.setChannelValue(c, values[j++]);
if (j == values.length) {
j = 0;
}
}
}
/**
* Check if this item represents RGB or RGBW.
*
* @return true if color item is RGBW.
*/
private boolean isRgbw() {
return channels.length % 4 == 0;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isStatusListener() {
if (updateDelay > MIN_UPDATE_DELAY && (channels.length == 3 || channels.length == 4)) {
return true;
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public void processStatusUpdate(int[] channelValues) {
if (channelValues.length != 3 && channelValues.length != 4) {
return;
}
HSBType cmd = new HSBType(new Color(channelValues[0], channelValues[1], channelValues[2]));
publishState(cmd);
}
/**
* {@inheritDoc}
*/
@Override
public int getFootPrint() {
if (channels == null) {
// default footprint
return 3;
}
// support RGB & RGBW
return isRgbw() ? 4 : 3;
}
}