/**
* 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.mcp23017.internal;
import java.util.Map;
import org.openhab.binding.mcp23017.MCP23017BindingProvider;
import org.openhab.core.binding.BindingConfig;
import org.openhab.core.items.Item;
import org.openhab.core.library.items.ContactItem;
import org.openhab.core.library.items.SwitchItem;
import org.openhab.model.item.binding.AbstractGenericBindingProvider;
import org.openhab.model.item.binding.BindingConfigParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.json.parsers.JSONParser;
import com.json.parsers.JsonParserFactory;
import com.pi4j.gpio.extension.mcp.MCP23017Pin;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinMode;
import com.pi4j.io.gpio.PinState;
/**
* This class is responsible for parsing the binding configuration.
*
* @author Diego A. Fliess
* @since 1.9.0
*/
public class MCP23017GenericBindingProvider extends AbstractGenericBindingProvider implements MCP23017BindingProvider {
private static final Logger logger = LoggerFactory.getLogger(MCP23017GenericBindingProvider.class);
/**
* {@inheritDoc}
*/
@Override
public String getBindingType() {
return "mcp23017";
}
@Override
public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException {
/* Only 'Switch' and 'Contact' types are allowed */
if (!((item instanceof SwitchItem) || (item instanceof ContactItem))) {
String message = "Item '" + item.getName() + "' is of type '" + item.getClass().getSimpleName() + "' ";
message = message + "while only 'Switch' or 'Contact' types are allowed";
logger.error("{}", message);
throw new BindingConfigParseException(message);
}
}
/**
* {@inheritDoc}
*/
@Override
public void processBindingConfiguration(String context, Item item, String bindingConfig)
throws BindingConfigParseException {
super.processBindingConfiguration(context, item, bindingConfig);
MCP23017BindingConfig config = new MCP23017BindingConfig();
// parse bindingConfig here ...
/*
* Configuration string should be a json in the form:
* Contact Test1 "Test 1" (Tests) { mcp23017="{ address:20, pin:'A0', mode:'DIGITAL_INPUT'}" }
* Switch Test2 "Test 2" (Tests) { mcp23017="{ address:20, pin:'B0', mode:'DIGITAL_OUTPUT', defaultState:'LOW'}"
* }
*/
JsonParserFactory factory = JsonParserFactory.getInstance();
JSONParser parser = factory.newJsonParser();
@SuppressWarnings("unchecked")
Map<String, Object> jsonData = parser.parseJson(bindingConfig);
try {
logger.debug("Process binding configuration in context {}", context);
config.setBusAddress(Integer.parseInt((String) jsonData.get("address"), 16));
config.setPin((Pin) MCP23017Pin.class.getField("GPIO_" + (String) jsonData.get("pin")).get(null));
config.setPinMode(PinMode.valueOf((String) jsonData.get("mode")));
if (item instanceof SwitchItem) {
config.setDefaultState(PinState.valueOf((String) jsonData.get("defaultState")));
}
} catch (IllegalArgumentException exception) {
final String message = "Illegal argument exception in configuration string ";
logger.error("{} '{}': {}", message, bindingConfig, exception.getMessage());
throw new BindingConfigParseException(message + "'" + bindingConfig + "'");
} catch (IllegalAccessException exception) {
final String message = "Illegal access exception in configuration string ";
logger.error("{} '{}': {}", message, bindingConfig, exception.getMessage());
throw new BindingConfigParseException(message + "'" + bindingConfig + "'");
} catch (NoSuchFieldException exception) {
final String message = "No such field exception in configuration string ";
logger.error("{} '{}': {}", message, bindingConfig, exception.getMessage());
throw new BindingConfigParseException(message + "'" + bindingConfig + "'");
} catch (SecurityException exception) {
final String message = "Security exception in configuration string ";
logger.error("{} '{}': {}", message, bindingConfig, exception.getMessage());
throw new BindingConfigParseException(message + "'" + bindingConfig + "'");
}
addBindingConfig(item, config);
}
/**
* This is a helper class holding binding specific configuration details
*
* @author Diego A. Fliess
* @since 1.9.0
*/
class MCP23017BindingConfig implements BindingConfig {
/** Configured mcp23017 Bus Address */
private int busAddress;
/** Configured pin number */
private Pin pin;
/** Configured pin default state */
private PinState defaultState;
/**
* Pin pinMode. If item type is <code>Switch</code> the pin
* pinMode should be out, if <code>Contact</code> - in
*/
private PinMode pinMode;
/**
* @return the busAddress
*/
public int getBusAddress() {
return busAddress;
}
/**
* @param busAddress the busAddress to set
*/
public void setBusAddress(int busAddress) {
this.busAddress = busAddress;
}
/**
* @return the pin
*/
public Pin getPin() {
return pin;
}
/**
* @param pin the pin to set
*/
public void setPin(Pin pin) {
this.pin = pin;
}
/**
* @return the defaultState
*/
public PinState getDefaultState() {
return defaultState;
}
/**
* @param defaultState the defaultState to set
*/
public void setDefaultState(PinState defaultState) {
this.defaultState = defaultState;
}
/**
* @return the pinMode
*/
public PinMode getPinMode() {
return pinMode;
}
/**
* @param pinMode the pinMode to set
*/
public void setPinMode(PinMode pinMode) {
this.pinMode = pinMode;
}
}
/* Internal method for searching itemName config */
private MCP23017BindingConfig getConfig(String itemName) {
MCP23017BindingConfig config = (MCP23017BindingConfig) bindingConfigs.get(itemName);
if (config == null) {
throw new IllegalArgumentException(
"The item name '" + itemName + "' is invalid or the item isn't configured");
}
return config;
}
/**
* @return the busAddress
*/
@Override
public int getBusAddress(String itemName) {
return getConfig(itemName).getBusAddress();
}
/**
* @return the pin
*/
@Override
public Pin getPin(String itemName) {
return getConfig(itemName).getPin();
}
/**
* @return the defaultState
*/
@Override
public PinState getDefaultState(String itemName) {
return getConfig(itemName).getDefaultState();
}
/**
* @return the pinMode
*/
@Override
public PinMode getPinMode(String itemName) {
return getConfig(itemName).getPinMode();
}
}