Package org.openhab.binding.dscalarm.internal.protocol

Source Code of org.openhab.binding.dscalarm.internal.protocol.API

/**
* 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.dscalarm.internal.protocol;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.openhab.binding.dscalarm.internal.DSCAlarmEventListener;
import org.openhab.binding.dscalarm.internal.connector.DSCAlarmConnector;
import org.openhab.binding.dscalarm.internal.connector.DSCAlarmConnectorType;
import org.openhab.binding.dscalarm.internal.connector.SerialConnector;
import org.openhab.binding.dscalarm.internal.connector.TCPConnector;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* A class that utilizes the Third Party Interface () for the EyezOn Envisalink 3/2DS
* @author Russell Stephens
* @since 1.6.0
*/
public class API {
 
  private static final Logger logger = LoggerFactory.getLogger(API.class);
      
  private DSCAlarmConnectorType connectorType = null;
  private DSCAlarmConnector dscAlarmConnector = null;
   
    /** API serial port name. **/
    private String apiSerialPort = "";

    /** API IP address. **/
    private String apiIP = "192.168.0.100";

  /** default TCP port. **/
  public static final int DEFAULT_BAUD_RATE = 9600;

  /** default TCP port. **/
  public static final int DEFAULT_TCP_PORT = 4025;

  /** Connection timeout in milliseconds **/
  private static final int CONNECTION_TIMEOUT = 5000;

  /** Default user code **/
  private static final String DEFAULT_USER_CODE = "1234";

  /** Default  password **/
  private static final String DEFAULT_PASSWORD = "user";

     /** Baud Rate for serial connection - set to default **/
  private int baudRate = DEFAULT_BAUD_RATE;

  /** User password for  network login - set to default **/
  private String password = DEFAULT_PASSWORD;
     /** DSC Alarm user code for some commands - set to default **/
  private String dscAlarmUserCode = DEFAULT_USER_CODE;

  private boolean connected = false;
  private int[] baudRates = {9600,19200,38400,57600,115200};
 
  /**
   * Constructor for Serial Connection
   *
   * @param serialPort
   * @param baud
   */ 
  public API(String serialPort, int baud) {
    if (StringUtils.isNotBlank(serialPort)) {
      apiSerialPort = serialPort;
    }

    if(isValidBaudRate(baud))
      baudRate = baud;

    connectorType = DSCAlarmConnectorType.SERIAL;
  }
      
  /**
   * Constructor for TCP connection
   *
   * @param ip
   * @param password
   * @param dscAlarmUserCode
   */
  public API(String ip, String password, String dscAlarmUserCode) {
    if (StringUtils.isNotBlank(ip)) {
      apiIP = ip;
    }

    if (StringUtils.isNotBlank(password)) {
      this.password = password;
    }

    if (StringUtils.isNotBlank(dscAlarmUserCode)) {
      this.dscAlarmUserCode = dscAlarmUserCode;
    }

    connectorType = DSCAlarmConnectorType.TCP;
  }

  /**
   * Add event listener
   *
   * @param listener
   **/
  public void addEventListener(DSCAlarmEventListener listener) {
    dscAlarmConnector.addEventListener(listener);
  }

  /**
   * Remove event listener
   *
   * @param listener
   **/
  public synchronized void removeEventListener(DSCAlarmEventListener listener) {
    dscAlarmConnector.removeEventListener(listener);
  }

  /**
   * Returns Connector Type
   *
   * @return connectorType
   **/
  public DSCAlarmConnectorType getConnectorType() {
    return connectorType;   
  }

  /**
   * Method to check if baud rate is valid
   *
   * @return boolean
   */
  private boolean isValidBaudRate(int baudRate) {
    boolean isValid = false;
   
    for (int i=0; i<baudRates.length; i++) {
      if(baudRate == baudRates[i])
        isValid = true;
    }
   
    return isValid;
  }
 
  /**
   * Return DSC Alarm User Code.
   **/
  public String getUserCode() {
    return dscAlarmUserCode;
  }
 
  /**
   * Connect to the DSC Alarm System through the EyezOn Envisalink 3/2DS or the DSC IT-100.
   **/
    public boolean open() {

      switch (connectorType) {
        case SERIAL:
        if(dscAlarmConnector == null) {
          dscAlarmConnector = new SerialConnector(apiSerialPort, baudRate);
        }
        break;
        case TCP:
            if(StringUtils.isNotBlank(apiIP) ) {
          if(dscAlarmConnector == null) {
            dscAlarmConnector = new TCPConnector(apiIP, DEFAULT_TCP_PORT, CONNECTION_TIMEOUT);
          }
            }
            else {
              logger.error("open(): Unable to Make API TCP Connection!");
              connected = false;
              return connected;
            }
            break;
          default:
            break;
      }
     
    dscAlarmConnector.open();
    connected = dscAlarmConnector.isConnected();
 
      if(connected) {
        if(connectorType == DSCAlarmConnectorType.TCP)
          sendCommand(APICode.NetworkLogin);
       
        connected = dscAlarmConnector.isConnected();
      }

      if(!connected)
        logger.error("open(): Unable to Make API Connection!");
     
    logger.debug("open(): Connected = {}, Connection Type: {}", connected ? true:false, connectorType);

    return connected;
    }
   
    /**
     * Close the connection to the DSC Alarm system.
     */
    public boolean close() {
    logger.debug("close(): Disconnecting from API Connection!");
    dscAlarmConnector.close();
    connected = dscAlarmConnector.isConnected();
      return connected;
    }

    /**
     * Read a API message received from the DSC Alarm system.
     */
    public String read() {         
    return dscAlarmConnector.read();
     }
      
    /**
     * Return Connected Status.
     */
     public boolean isConnected() {
         return dscAlarmConnector.isConnected();
     }

     /**
      * Send an API command to the DSC Alarm system.
      *
      * @param apiCode
      * @param apiData
      * @return
      */
     public boolean sendCommand(APICode apiCode, String... apiData) {
      boolean successful = false;
      boolean validCommand = false;
     
      String command = apiCode.getCode();
      String data = "";
    
     switch (apiCode) {
      case Poll: /*000*/
      case StatusReport: /*001*/
        validCommand = true;
        break;
       case LabelsRequest: /*002*/
         if(!connectorType.equals(DSCAlarmConnectorType.SERIAL)) {
           break;         
         }
        validCommand = true;
         break;
      case NetworkLogin: /*005*/
         if(!connectorType.equals(DSCAlarmConnectorType.TCP)) {
           break;         
         }
        
         if (password == null || password.length() < 1 || password.length() > 6) {
           logger.error("sendCommand(): Password is invalid, must be between 1 and 6 chars", password);
           break;
         }
        data = password;
        validCommand = true;
         break;
       case DumpZoneTimers: /*008*/
         if(!connectorType.equals(DSCAlarmConnectorType.TCP)) {
           break;         
         }
        validCommand = true;
         break;
       case SetTimeDate: /*010*/
         Date date = new Date();
         SimpleDateFormat dateTime = new SimpleDateFormat("HHmmMMddYY");
         data = dateTime.format(date);
        validCommand = true;
         break;
       case CommandOutputControl: /*020*/
         if (apiData[0] == null || !apiData[0].matches("[1-8]")) {
             logger.error("sendCommand(): Partition number must be a single character string from 1 to 8, it was: " + apiData[0]);
            break;
         }
         if (apiData[1] == null || !apiData[1].matches("[1-4]")) {
             logger.error("sendCommand(): Output number must be a single character string from 1 to 4, it was: " + apiData[1]);
           break;         
         }

         data = apiData[0];
         validCommand = true;
         break;
       case KeepAlive: /*074*/
         if(!connectorType.equals(DSCAlarmConnectorType.TCP)) {
           break;         
         }
       case PartitionArmControlAway: /*030*/
       case PartitionArmControlStay: /*031*/
       case PartitionArmControlZeroEntryDelay: /*032*/
         if (apiData[0] == null || !apiData[0].matches("[1-8]")) {
             logger.error("sendCommand(): Partition number must be a single character string from 1 to 8, it was: {}", apiData[0]);
           break;         
         }
        data = apiData[0];
        validCommand = true;
         break;
       case PartitionArmControlWithUserCode: /*033*/
       case PartitionDisarmControl: /*040*/
         if (apiData[0] == null || !apiData[0].matches("[1-8]")) {
             logger.error("sendCommand(): Partition number must be a single character string from 1 to 8, it was: {}", apiData[0]);
           break;
         }
        
         if (dscAlarmUserCode == null || dscAlarmUserCode.length() < 4 || dscAlarmUserCode.length() > 6) {
           logger.error("sendCommand(): User Code is invalid, must be between 4 and 6 chars: {}", dscAlarmUserCode);
           break;
         }
        data = apiData[0] + dscAlarmUserCode;
        validCommand = true;
          break;
       case VirtualKeypadControl: /*058*/
         if(!connectorType.equals(DSCAlarmConnectorType.SERIAL)) {
           break;         
         }
       case TimeStampControl: /*055*/
       case TimeDateBroadcastControl: /*056*/
       case TemperatureBroadcastControl: /*057*/
         if (apiData[0] == null || !apiData[0].matches("[0-1]")) {
              logger.error("sendCommand(): Value must be a single character string of 0 or 1: {}", apiData[0]);
           break;
         }
        data = apiData[0];
        validCommand = true;
         break;
       case TriggerPanicAlarm: /*060*/
         if (apiData[0] == null || !apiData[0].matches("[1-8]")) {
              logger.error("sendCommand(): Partition number must be a single character string from 1 to 8, it was: {}", apiData[0]);
            break;
         }    
         
         if (apiData[1] == null || !apiData[1].matches("[1-3]")) {
             logger.error("sendCommand(): FAPcode must be a single character string from 1 to 3, it was: {}", apiData[1]);
           break;
         }
        data = apiData[0] + apiData[1];
        validCommand = true;
         break;
       case KeyStroke: /*070*/
         if (apiData[0] == null || apiData[0].length() != 1 || !apiData[0].matches("[0-9]|A|#|\\*")) {
             logger.error("sendCommand(): \'keystroke\' must be a single character string from 0 to 9, *, #, or A, it was: {}", apiData[0]);
           break;
         }
        data = apiData[0];
        validCommand = true;
         break;
       case KeySequence: /*071*/
         if(!connectorType.equals(DSCAlarmConnectorType.TCP)) {
           break;
         }
        
         if (apiData[0] == null || apiData[0].length() > 6 || !apiData[0].matches("(\\d|#|\\*)+")) {
             logger.error("sendCommand(): \'keysequence\' must be a string of up to 6 characters consiting of 0 to 9, *, or #, it was: {}", apiData[0]);
           break;
         }
        data = apiData[0];
        validCommand = true;
         break;
       case CodeSend: /*200*/
         if (dscAlarmUserCode == null || dscAlarmUserCode.length() < 4 || dscAlarmUserCode.length() > 6) {
           logger.error("sendCommand(): Access Code is invalid, must be between 4 and 6 chars: {}", apiData[0]);
           break;
         }
        data = dscAlarmUserCode;
        validCommand = true;
         break;

       default:
         validCommand = false;
        break;

     }    

     if(validCommand) {
       APICommand apiCommand = new APICommand();
       apiCommand.setAPICommand(command, data);
        dscAlarmConnector.write(apiCommand.toString());
        successful = true;
        logger.debug("sendCommand(): Command Sent - {}",apiCommand.toString());
      }
      else
        logger.error("sendCommand(): Command Not Sent - Invalid!");
      
      return successful;
    }
}
TOP

Related Classes of org.openhab.binding.dscalarm.internal.protocol.API

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.