/**
* 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.rfxcom.internal;
import java.io.InvalidClassException;
import org.openhab.binding.rfxcom.RFXComBindingProvider;
import org.openhab.binding.rfxcom.RFXComValueSelector;
import org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType;
import org.openhab.binding.rfxcom.internal.messages.RFXComMessageFactory;
import org.openhab.core.binding.BindingConfig;
import org.openhab.core.items.Item;
import org.openhab.model.item.binding.AbstractGenericBindingProvider;
import org.openhab.model.item.binding.BindingConfigParseException;
/**
* <p>
* This class can parse information from the generic binding format and provides
* RFXCOM device binding information from it.
* </p>
*
* <p>
* The syntax of the binding configuration strings accepted is the following:
* <p>
* <p>
* <code>
* in: rfxcom:"<DeviceId:ValueSelector"
* <p>
* out: rfxcom:">DeviceId:PacketType.SubType:ValueSelector"
* </code>
* <p>
* <p>
* Examples for valid binding configuration strings:
*
* <ul>
* <li><code>rfxcom="<2264:Temperature"</code></li>
* <li><code>rfxcom="<2264:Humidity"</code></li>
* <li><code>rfxcom="<635602.1:Command"</code></li>
* <li><code>rfxcom="<635602.2:Command"</code></li>
* <li><code>rfxcom">635602.1:LIGHTING2.AC:Command"</code></li>
* </ul>
*
*
* @author Pauli Anttila
* @since 1.2.0
*/
public class RFXComGenericBindingProvider extends AbstractGenericBindingProvider implements RFXComBindingProvider {
/**
* {@inheritDoc}
*/
@Override
public String getBindingType() {
return "rfxcom";
}
/**
* @{inheritDoc}
*/
@Override
public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException {
}
/**
* {@inheritDoc}
*/
@Override
public void processBindingConfiguration(String context, Item item, String bindingConfig)
throws BindingConfigParseException {
super.processBindingConfiguration(context, item, bindingConfig);
RFXComBindingConfig config = new RFXComBindingConfig();
String valueSelectorString = null;
if (bindingConfig.startsWith("<")) {
String[] configParts = bindingConfig.trim().split(":");
if (configParts.length != 2) {
throw new BindingConfigParseException("RFXCOM binding must contain two parts separated by ':'");
}
config.id = configParts[0].trim().replace("<", "");
config.inBinding = true;
valueSelectorString = configParts[1].trim();
} else if (bindingConfig.startsWith(">")) {
String[] configParts = bindingConfig.trim().split(":");
config.id = configParts[0].trim().replace(">", "");
config.inBinding = false;
String[] types = configParts[1].trim().split("\\.");
if (types.length != 2) {
throw new BindingConfigParseException(
"RFXCOM out binding second field should contain 2 parts separated by '.'");
}
try {
config.packetType = RFXComMessageFactory.convertPacketType(types[0].trim());
} catch (IllegalArgumentException e) {
throw new BindingConfigParseException("Invalid packet type '" + types[0] + "'!");
}
try {
config.subType = RFXComMessageFactory.getMessageInterface(config.packetType)
.convertSubType(types[1].trim());
} catch (Exception e) {
throw new BindingConfigParseException(
"Invalid sub type '" + types[1] + "' in type '" + config.packetType + "'!");
}
valueSelectorString = configParts[2].trim();
} else {
throw new BindingConfigParseException("RFXCOM binding should start < or > character!");
}
try {
RFXComValueSelector.validateBinding(valueSelectorString, item.getClass());
config.valueSelector = RFXComValueSelector.getValueSelector(valueSelectorString);
} catch (IllegalArgumentException e1) {
throw new BindingConfigParseException("Invalid value selector '" + valueSelectorString + "'!");
} catch (InvalidClassException e1) {
throw new BindingConfigParseException(
"Invalid item type for value selector '" + valueSelectorString + "'!");
}
addBindingConfig(item, config);
}
static class RFXComBindingConfig implements BindingConfig {
String id;
RFXComValueSelector valueSelector;
boolean inBinding;
PacketType packetType;
Object subType;
}
@Override
public String getId(String itemName) {
RFXComBindingConfig config = getBindingConfig(itemName);
return config != null ? config.id : null;
}
@Override
public RFXComValueSelector getValueSelector(String itemName) {
RFXComBindingConfig config = getBindingConfig(itemName);
return config != null ? config.valueSelector : null;
}
private RFXComBindingConfig getBindingConfig(String itemName) {
return (RFXComBindingConfig) bindingConfigs.get(itemName);
}
@Override
public boolean isInBinding(String itemName) {
RFXComBindingConfig config = getBindingConfig(itemName);
return config != null ? config.inBinding : null; // null as boolean?
}
@Override
public PacketType getPacketType(String itemName) {
RFXComBindingConfig config = getBindingConfig(itemName);
return config != null ? config.packetType : null;
}
@Override
public Object getSubType(String itemName) {
RFXComBindingConfig config = getBindingConfig(itemName);
return config != null ? config.subType : null;
}
@Override
public Boolean autoUpdate(final String itemName) {
if (!providesBindingFor(itemName)) {
return null;
}
RFXComBindingConfig bindingConfig = getBindingConfig(itemName);
if (bindingConfig == null) {
return null;
}
if (bindingConfig.inBinding) {
return true;
}
return false;
}
}