Package org.openhab.binding.urtsi.internal

Source Code of org.openhab.binding.urtsi.internal.UrtsiBinding

/**
* Copyright (c) 2010-2014, openHAB.org and others.
*
* 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.urtsi.internal;

import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.openhab.binding.urtsi.UrtsiBindingProvider;
import org.openhab.core.binding.AbstractBinding;
import org.openhab.core.library.types.StopMoveType;
import org.openhab.core.library.types.UpDownType;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.types.Type;
import org.openhab.model.item.binding.BindingConfigParseException;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Main implementation of the Somfy URTSI II Binding. This binding is
* responsible for delegating the received commands and updates to the
* {@link UrtsiDevice}.
*
* @author Oliver Libutzki
* @since 1.3.0
*
*/
public class UrtsiBinding extends AbstractBinding<UrtsiBindingProvider>
    implements ManagedService {

  private final static Logger logger = LoggerFactory
      .getLogger(UrtsiBinding.class);

  private final static String COMMAND_UP = "U";
  private final static String COMMAND_DOWN = "D";
  private final static String COMMAND_STOP = "S";

  private final static Pattern EXTRACT_URTSI_CONFIG_PATTERN = Pattern
      .compile("^(.*?)\\.(port)$");

  /**
   * Maps the device id to a URTSI device. This is needed if you use multiple
   * ports for multiple urtsi devices.
   */
  private final Map<String, UrtsiDevice> idToDeviceMap = new HashMap<String, UrtsiDevice>();

  /**
   * The method determines the appropriate
   * {@link org.openhab.core.binding.BindingProvider} and uses it to get the
   * corresponding URTSI device and channel. Bases on the given type a command
   * is send to the device.
   *
   * @param itemName
   *            name of the item
   * @param type
   *            Type of the command or status update
   * @return Returns true, if the command has been executed successfully.
   *         Returns false otherwise.
   * @throws BindingConfigParseException
   */
  private boolean sendToUrtsi(String itemName, Type type) {
    UrtsiBindingProvider provider = null;
    if (!providers.isEmpty()) {
      provider = providers.iterator().next();
    }
    if (provider == null) {
      if (logger.isErrorEnabled()) {
        logger.error("doesn't find matching binding provider [itemName={}, type={}]", itemName, type);
      }
      return false;
    }
    String urtsiDeviceId = provider.getDeviceId(itemName);
    UrtsiDevice urtsiDevice = idToDeviceMap.get(urtsiDeviceId);
   
    if (urtsiDevice == null) {
      if (logger.isErrorEnabled()) {
        logger.error("No serial port has been configured for urtsi device id '" + urtsiDeviceId +"'");
      }
      return false;
    }
   
    int channel = provider.getChannel(itemName);
    int address = provider.getAddress(itemName);
   
    if (urtsiDevice != null) {
      if (logger.isDebugEnabled()) {
        logger.debug("Send to URTSI for item: " + itemName + "; Type: " + type);
      }
      String actionKey = null;
      if (type instanceof UpDownType) {
        switch ((UpDownType)type) {
          case UP :
            actionKey = COMMAND_UP;
            break;
          case
          DOWN : actionKey = COMMAND_DOWN;
          break;
        }
      } else if (type instanceof StopMoveType) {
        switch ((StopMoveType)type) {
          case STOP :
            actionKey = COMMAND_STOP;
            break;
          default:
            break;
        }
      }
     

      if (logger.isDebugEnabled()) {
        logger.debug("Action key: " + actionKey);
      }
      if (actionKey != null) {
        String channelString = String.format("%02d", channel);
        String addressString = String.format("%02d", address);
        String command = addressString + channelString + actionKey;
        boolean executedSuccessfully = urtsiDevice.writeString(command);
        if (!executedSuccessfully) {
          if (logger.isErrorEnabled()) {
            logger.error("Command has not been processed [itemName={}, command={}]", itemName, command);
          }
        }
        return executedSuccessfully;
      }
    }
    return false;
  }

  /**
   * The method delegates the received command to the URTSI device and updates
   * the item's state, if the command has been executed successfully.
   */
  protected void internalReceiveCommand(String itemName, Command command) {
    if (logger.isDebugEnabled()) {
      logger.debug("Received command for " + itemName + "! Command: " + command);
    }
    boolean executedSuccessfully = sendToUrtsi(itemName, command);
    if (executedSuccessfully && command instanceof State) {
      eventPublisher.postUpdate(itemName, (State)command);
    }
  }
 
  /**
   * The method delegates the received state-update to the URTSI device.
   */
  protected void internalReceiveUpdate(String itemName, State newState) {
    if (logger.isDebugEnabled()) {
      logger.debug("Received update for " + itemName + "! New state: " + newState);
    }
    sendToUrtsi(itemName, newState);
  }
 
  /**
   * Parses the global configuration file.
   * Expected values:
   * urtsi.<deviceid>.port=<serialport>
   */
  public void updated(Dictionary<String, ? > configthrows ConfigurationException {
   
    if (config != null) {
      Enumeration<String> keys = config.keys();
      while (keys.hasMoreElements()) {
        String key = keys.nextElement();
        logger.debug("Processing key '" + key + "'");
        // the config-key enumeration contains additional keys that we
        // don't want to process here ...
        if (key != "service.pid") {
         
          Matcher matcher = EXTRACT_URTSI_CONFIG_PATTERN.matcher(key);
          if (!matcher.matches()) {
            logger.debug("given config key '"
                + key
                + "' does not follow the expected pattern '<id>.port'");
          } else {
            matcher.reset();
            matcher.find();
   
            String deviceId = matcher.group(1);
            UrtsiDevice urtsiDevice = idToDeviceMap.get(deviceId);
            if (urtsiDevice == null) {
              String configKey = matcher.group(2);
              String value = (String)config.get(key);
              String port = null;
              if ("port".equals(configKey)) {
                port = value;
              } else {
                throw new ConfigurationException(configKey, "the given config key '" + configKey + "' is unknown");
              }
              urtsiDevice = new UrtsiDevice(port);
              try {
                System.setProperty("gnu.io.rxtx.SerialPorts", port);
                urtsiDevice.initialize();
              } catch (InitializationException e) {
                throw new ConfigurationException(configKey,
                    "Could not open serial port " + port + ": "
                        + e.getMessage());
              } catch (Throwable e) {
                throw new ConfigurationException(configKey,
                    "Could not open serial port " + port + ": "
                        + e.getMessage());
              }
              idToDeviceMap.put(deviceId, urtsiDevice);
            }
          } 
        }
      }
    }
  }

}
TOP

Related Classes of org.openhab.binding.urtsi.internal.UrtsiBinding

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.