/** * 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.km200.internal; import java.util.HashMap; import java.util.HashSet; import java.util.Map.Entry; import java.util.Set; import org.openhab.binding.km200.KM200BindingProvider; import org.openhab.core.binding.BindingConfig; import org.openhab.core.items.Item; import org.openhab.core.library.items.DateTimeItem; import org.openhab.core.library.items.NumberItem; import org.openhab.core.library.items.StringItem; 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; /** * This class can parse information from the generic binding format and * provides KM200 binding information from it. It registers as a * {@link KM200BindingProvider} service as well. * * @author Markus Eckhardt * * @since 1.9.0 */ public class KM200GenericBindingProvider extends AbstractGenericBindingProvider implements KM200BindingProvider { static final Logger logger = LoggerFactory.getLogger(KM200GenericBindingProvider.class); /** * {@inheritDoc} */ @Override public String getBindingType() { return "km200"; } /** * @{inheritDoc} */ @Override public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException { if (!(item instanceof SwitchItem || item instanceof StringItem || item instanceof NumberItem || item instanceof DateTimeItem)) { throw new BindingConfigParseException("item '" + item.getName() + "' is of type '" + item.getClass().getSimpleName() + "', only Switch- String- DateTime- and NumberItems are allowed - please check your *.items configuration"); } } /** * {@inheritDoc} */ @Override public void processBindingConfiguration(String context, Item item, String bindingConfig) throws BindingConfigParseException { KM200BindingConfig config = parseBindingConfig(item, bindingConfig); addBindingConfig(item, config); super.processBindingConfiguration(context, item, bindingConfig); } /** * Checks if the bindingConfig contains a valid binding type and returns an appropriate instance. * * @param item * @param bindingConfig * * @throws BindingConfigParseException if bindingConfig is no valid binding type */ protected KM200BindingConfig parseBindingConfig(Item item, String bindingConfig) throws BindingConfigParseException { String service = null, current = null; HashMap<String, String> parameterMap = new HashMap<String, String>(); /* Check whether some defined services are used */ logger.info("Bind Config: {}", bindingConfig); if (bindingConfig.trim().equals(KM200BindingProvider.DATE_TIME)) { return new KM200BindingConfig(item.getClass(), KM200BindingProvider.DATE_TIME, "/gateway/DateTime", parameterMap); } if (bindingConfig.trim().equals(KM200BindingProvider.SYS_BRAND)) { return new KM200BindingConfig(item.getClass(), KM200BindingProvider.SYS_BRAND, "/system/brand", parameterMap); } if (bindingConfig.trim().equals(KM200BindingProvider.SYS_TYPE)) { return new KM200BindingConfig(item.getClass(), KM200BindingProvider.SYS_TYPE, "/system/appliance/type", parameterMap); } if (bindingConfig.trim().equals(KM200BindingProvider.SYS_STATE)) { return new KM200BindingConfig(item.getClass(), KM200BindingProvider.SYS_STATE, "/system/healthStatus", parameterMap); } if (bindingConfig.trim().equals(KM200BindingProvider.VER_FIRMWARE)) { return new KM200BindingConfig(item.getClass(), KM200BindingProvider.VER_FIRMWARE, "/gateway/versionFirmware", parameterMap); } if (bindingConfig.trim().equals(KM200BindingProvider.VER_HARDWARE)) { return new KM200BindingConfig(item.getClass(), KM200BindingProvider.VER_HARDWARE, "/gateway/versionHardware", parameterMap); } /* Maybe it's a configuration */ /* Configuration string should be in the form "service:/gateway/versionFirmware" */ /* Available options for a SwitchItem are on:xxx and off:yyy with a allowed value xxx|yyy */ String[] keyTypeStructure = bindingConfig.split("\\s+"); logger.debug("Bind Config nbr: {}", keyTypeStructure.length); if (keyTypeStructure.length > 3) { logger.error("Incorrect number of structures in configuration string '{}'", bindingConfig); throw new BindingConfigParseException( "Incorrect number of structures in configuration string '" + bindingConfig + "'"); } for (String structure : keyTypeStructure) { String[] keyValueStructure = structure.split(":"); if (keyValueStructure.length != 2) { logger.error("Incorrect key:value structure in configuration string '{}'", bindingConfig); throw new BindingConfigParseException( "Incorrect key:value structure in configuration string '" + bindingConfig + "'"); } String key = keyValueStructure[0]; String value = keyValueStructure[1]; if (key.equals("service")) { service = value; if (!service.contains("/")) { logger.error("Wrong service string without / in configuration string '{}'", bindingConfig); throw new BindingConfigParseException( "Wrong service string without / in configuration string '" + bindingConfig + "'"); } } else if (key.equals("current")) { current = value; if (!current.contains("/")) { logger.error("Wrong current string without / in configuration string '{}'", bindingConfig); throw new BindingConfigParseException( "Wrong current string without / in configuration string '" + bindingConfig + "'"); } parameterMap.put(key, current); } else if (key.equals("on") || key.equals("off")) { parameterMap.put(key, value); } else { logger.error("Unsupported key: ({}) in configuration string: '{}'", key, bindingConfig); throw new BindingConfigParseException( "Unsupported key (" + key + ") in configuration string '" + bindingConfig + "'"); } } if (parameterMap.containsKey("on") || parameterMap.containsKey("off")) { if (!(parameterMap.containsKey("on") && parameterMap.containsKey("off"))) { throw new BindingConfigParseException( "Unsupported combination, 'on' and 'off' have to be configured together '" + bindingConfig + "'"); } } return new KM200BindingConfig(item.getClass(), KM200BindingProvider.DIRECT_SERVICE, service, parameterMap); } @Override public Class<? extends Item> getItemType(String itemName) { KM200BindingConfig config = (KM200BindingConfig) bindingConfigs.get(itemName); return config != null ? config.getItemType() : null; } @Override public String getType(String itemName) { KM200BindingConfig config = (KM200BindingConfig) bindingConfigs.get(itemName); return config != null ? config.getType() : null; } @Override public String getService(String itemName) { KM200BindingConfig config = (KM200BindingConfig) bindingConfigs.get(itemName); return config != null ? config.getService() : null; } @Override public HashMap<String, String> getParameter(String itemName) { KM200BindingConfig config = (KM200BindingConfig) bindingConfigs.get(itemName); return config != null ? config.getParameter() : null; } @Override public String[] getItemNamesForType(String eventType) { Set<String> itemNames = new HashSet<>(); for (Entry<String, BindingConfig> entry : bindingConfigs.entrySet()) { KM200BindingConfig fbConfig = (KM200BindingConfig) entry.getValue(); if (fbConfig.getType().equals(eventType)) { itemNames.add(entry.getKey()); } } return itemNames.toArray(new String[itemNames.size()]); } static class KM200BindingConfig implements BindingConfig { final private Class<? extends Item> itemType; final private String type; final private String service; private HashMap<String, String> parameterMap = null; public KM200BindingConfig(Class<? extends Item> itemType, String type, String service, HashMap<String, String> parameter) { this.itemType = itemType; this.type = type; this.service = service; this.parameterMap = parameter; } public Class<? extends Item> getItemType() { return itemType; } public String getType() { return type; } public String getService() { return service; } public HashMap<String, String> getParameter() { return parameterMap; } } }