com.freedomotic.plugins.devices.tcw122bcm.Tcw122bcm.java Source code

Java tutorial

Introduction

Here is the source code for com.freedomotic.plugins.devices.tcw122bcm.Tcw122bcm.java

Source

/**
 *
 * Copyright (c) 2009-2016 Freedomotic team http://freedomotic.com
 *
 * This file is part of Freedomotic
 *
 * This Program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2, or (at your option) any later version.
 *
 * This Program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * Freedomotic; see the file COPYING. If not, see
 * <http://www.gnu.org/licenses/>.
 */
package com.freedomotic.plugins.devices.tcw122bcm;

import com.freedomotic.api.EventTemplate;
import com.freedomotic.api.Protocol;
import com.freedomotic.app.Freedomotic;
import com.freedomotic.events.ProtocolRead;
import com.freedomotic.exceptions.UnableToExecuteException;
import com.freedomotic.reactions.Command;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.codec.binary.Base64;

public class Tcw122bcm extends Protocol {

    private static final Logger LOG = Logger.getLogger(Tcw122bcm.class.getName());
    Map<String, Board> devices = new HashMap<String, Board>();
    private static int BOARD_NUMBER = 1;
    private static int POLLING_TIME = 1000;
    private Socket socket = null;
    private DataOutputStream outputStream = null;
    private BufferedReader inputStream = null;
    private String[] address = null;
    private int SOCKET_TIMEOUT = configuration.getIntProperty("socket-timeout", 1000);
    private int SNMP_PORT = configuration.getIntProperty("snmp-port", 161);
    private String SNMP_COMMUNITY = configuration.getStringProperty("snmp-community", "public");
    private String SNMP_OID = configuration.getStringProperty("snmp-oid", "1.3.6.1.4.38783");
    private String D1_VALUE = configuration.getStringProperty("digital-input1-value", "3.1.0");
    private String D2_VALUE = configuration.getStringProperty("digital-input2-value", "3.2.0");
    private String R1_STATE = configuration.getStringProperty("r1", "3.3.0");
    private String R2_STATE = configuration.getStringProperty("r2", "3.5.0");
    private String A1_VALUE = configuration.getStringProperty("analog-input1-value", "3.7.0");
    private String A2_VALUE = configuration.getStringProperty("analog2-input2-value", "3.8.0");
    private String T1_VALUE = configuration.getStringProperty("temperature1-value", "3.9.0");
    private String T2_VALUE = configuration.getStringProperty("temperature2-value", "3.10.0");
    private String H1_VALUE = configuration.getStringProperty("humidity1-value", "3.11.0");
    private String H2_VALUE = configuration.getStringProperty("humidity2-value", "3.12.0");
    private String HTTP_AUTHENTICATION = configuration.getStringProperty("http-authentication", "true");
    private String USERNAME = configuration.getStringProperty("username", "admin");
    private String PASSWORD = configuration.getStringProperty("password", "admin");

    /**
     * Initializations
     */
    public Tcw122bcm() {
        super("TCW122B-CM", "/tcw122bcm/tcw122bcm-manifest.xml");
        setPollingWait(POLLING_TIME);
    }

    // load boards data from file manifest tcw122bcm.xml
    private void loadBoards() {
        if (devices == null) {
            devices = new HashMap<String, Board>();
        }
        setDescription("Reading status changes from"); //empty description
        for (int i = 0; i < BOARD_NUMBER; i++) {
            String ipToQuery;
            String alias;
            String relayObjectTemplate;
            String temperatureObjectTemplate;
            String humidityObjectTemplate;
            int portNumber;
            alias = configuration.getTuples().getStringProperty(i, "alias", "default");
            relayObjectTemplate = configuration.getTuples().getStringProperty(i, "relay-template", "light");
            temperatureObjectTemplate = configuration.getTuples().getStringProperty(i, "temperature-template",
                    "thermostat");
            humidityObjectTemplate = configuration.getTuples().getStringProperty(i, "relay-humidity", "hygrometer");
            ipToQuery = configuration.getTuples().getStringProperty(i, "ip-to-query", "192.168.1.201");
            portNumber = configuration.getTuples().getIntProperty(i, "port-number", 80);
            Board board = new Board(alias, ipToQuery, portNumber, "2000", "2000", "2000", "2000", "2000", "2000",
                    "2000", "2000", "2000", "2000", relayObjectTemplate, temperatureObjectTemplate,
                    humidityObjectTemplate);
            devices.put(alias, board);
            setDescription(getDescription() + " " + ipToQuery);
        }
    }

    /*
     * Sensor side
     */
    @Override
    public void onStart() {
        POLLING_TIME = configuration.getIntProperty("polling-time", 1000);
        // number of configured boards in manifest file
        BOARD_NUMBER = configuration.getTuples().size();
        setPollingWait(POLLING_TIME);
        loadBoards();
    }

    @Override
    public void onStop() {
        //release resources
        devices.clear();
        devices = null;
        setPollingWait(-1); //disable polling
        //display the default description
        setDescription(configuration.getStringProperty("description", "TCW122B-CM"));
    }

    @Override
    protected void onRun() {
        Set keys = devices.keySet();
        Iterator keyIter = keys.iterator();
        while (keyIter.hasNext()) {
            String alias = (String) keyIter.next();
            Board board = (Board) devices.get(alias);
            evaluateDiff(board);
        }
        try {
            Thread.sleep(POLLING_TIME);
        } catch (InterruptedException ex) {
            Logger.getLogger(Tcw122bcm.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    // }

    private void sendEvent(String objectAddress, String eventProperty, String eventValue, String objectTemplate) {
        ProtocolRead event = new ProtocolRead(this, "tcw122bcm", objectAddress);
        event.addProperty(eventProperty, eventValue);
        //publish the event on the messaging bus
        this.notifyEvent(event);
    }

    // this method sends a Freedomotic event only if there is any change in input values or relays 
    // @param board  
    //        board object to evaluate
    // @return
    //        no value 
    private void evaluateDiff(Board board) {
        //String address = board.getIpAddress() + ":" + board.getPortNumber();
        //String address = board.getAlias();
        String value = null;
        MYSNMP snmpRequest = new MYSNMP();
        //temperature1
        value = snmpRequest.SNMP_GET(board.getIpAddress(), SNMP_PORT, SNMP_OID + "." + T1_VALUE, SNMP_COMMUNITY);
        if (!value.equalsIgnoreCase(board.getTemperature1())) {
            sendEvent(address + ":T1", "sensor.temperature", value, board.getTemperatureObjectTemplate());
            board.setTemperature1(value);
        }
        //temperature2
        value = snmpRequest.SNMP_GET(board.getIpAddress(), SNMP_PORT, SNMP_OID + "." + T2_VALUE, SNMP_COMMUNITY);
        if (!value.equalsIgnoreCase(board.getTemperature2())) {
            sendEvent(address + ":T2", "sensor.temperature", value, board.getTemperatureObjectTemplate());
            board.setTemperature2(value);
        }
        //humidity1
        value = snmpRequest.SNMP_GET(board.getIpAddress(), SNMP_PORT, SNMP_OID + "." + H1_VALUE, SNMP_COMMUNITY);
        if (!value.equalsIgnoreCase(board.getHumidity1())) {
            sendEvent(address + ":H1", "sensor.humidity", value, board.getHumidityObjectTemplate());
            board.setHumidity1(value);
        }
        //humidity2
        value = snmpRequest.SNMP_GET(board.getIpAddress(), SNMP_PORT, SNMP_OID + "." + H2_VALUE, SNMP_COMMUNITY);
        if (!value.equalsIgnoreCase(board.getHumidity2())) {
            sendEvent(address + ":H2", "sensor.humidity", value, board.getHumidityObjectTemplate());
            board.setHumidity2(value);
        }
        //digital input 1
        value = snmpRequest.SNMP_GET(board.getIpAddress(), SNMP_PORT, SNMP_OID + "." + D1_VALUE, SNMP_COMMUNITY);
        if (!value.equalsIgnoreCase(board.getDigitalInput1())) {
            sendEvent(address + ":D1", "digital.input.value", value, "default");
            board.setDigitalInput1(value);
        }
        //digital input 2
        value = snmpRequest.SNMP_GET(board.getIpAddress(), SNMP_PORT, SNMP_OID + "." + D2_VALUE, SNMP_COMMUNITY);
        if (!value.equalsIgnoreCase(board.getDigitalInput2())) {
            sendEvent(address + ":D2", "digital.input.value", value, "default");
            board.setDigitalInput2(value);
        }
        //analog input 1
        value = snmpRequest.SNMP_GET(board.getIpAddress(), SNMP_PORT, SNMP_OID + "." + A1_VALUE, SNMP_COMMUNITY);
        if (!value.equalsIgnoreCase(board.getAnalogInput1())) {
            sendEvent(address + ":A1", "analog.input.value", value, "default");
            board.setAnalogInput1(value);
        }
        //analog input 2
        value = snmpRequest.SNMP_GET(board.getIpAddress(), SNMP_PORT, SNMP_OID + "." + A2_VALUE, SNMP_COMMUNITY);
        if (!value.equalsIgnoreCase(board.getAnalogInput2())) {
            sendEvent(address + ":A2", "analog.input.value", value, "default");
            board.setAnalogInput2(value);
        }
        //relay1 state
        value = snmpRequest.SNMP_GET(board.getIpAddress(), SNMP_PORT, SNMP_OID + "." + R1_STATE, SNMP_COMMUNITY);
        if (!value.equalsIgnoreCase(board.getRelay1())) {
            sendEvent(address + ":R1", "relay.state", value, board.getRelayObjectTemplate());
            board.setRelay1(value);
        }
        //relay2 state
        value = snmpRequest.SNMP_GET(board.getIpAddress(), SNMP_PORT, SNMP_OID + "." + R2_STATE, SNMP_COMMUNITY);
        if (!value.equalsIgnoreCase(board.getRelay2())) {
            sendEvent(address + ":R2", "relay.state", value, board.getRelayObjectTemplate());
            board.setRelay2(value);
        }
    }

    /**
     * Actuator side
     */
    @Override
    public void onCommand(Command c) throws UnableToExecuteException {
        String delimiter = configuration.getProperty("address-delimiter");
        Integer control = 0;
        address = c.getProperty("address").split(delimiter);
        //retrieve the board handle from alias key 
        Board board = (Board) devices.get(address[0]);
        String hostname = board.getIpAddress();
        int hostport = board.getPortNumber();
        String relay = address[1].toLowerCase();
        //convert control 
        if (c.getProperty("control").equalsIgnoreCase("ON")) {
            control = 1;
        }
        if (c.getProperty("control").equalsIgnoreCase("OFF")) {
            control = 0;
        }
        // call the method for changing relay status
        changeRelayStatus(hostname, hostport, relay, control);
    }

    // This method changes the relay status using http commands
    // If set in the configuration file it uses the http authentication 
    // @param hostname  
    //        TCW122B-CM ip address
    // @param hostport  
    //        TCW122B-CM tcp port (default value 80)
    // @param relayNumber  
    //        relay number - allowed values 1,2
    // @param control  
    //        action to perform - allowed value 0 (off), 1 (on)
    // @return
    //        no value 
    private void changeRelayStatus(String hostname, int hostport, String relayNumber, int control) {
        try {
            String authString = USERNAME + ":" + PASSWORD;
            //System.out.println("auth string: " + authString);
            byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
            String authStringEnc = new String(authEncBytes);
            //System.out.println("Base64 encoded auth string: " + authStringEnc); //FOR DEBUG
            //Create a URL for the desired  page 
            URL url = new URL("http://" + hostname + ":" + hostport + "/?" + relayNumber + "=" + control);
            LOG.info("Freedomotic sends the command " + url);
            URLConnection urlConnection = url.openConnection();
            // if required set the authentication
            if (HTTP_AUTHENTICATION.equalsIgnoreCase("true")) {
                urlConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
            }
            InputStream is = urlConnection.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            int numCharsRead;
            char[] charArray = new char[1024];
            StringBuffer sb = new StringBuffer();
            while ((numCharsRead = isr.read(charArray)) > 0) {
                sb.append(charArray, 0, numCharsRead);
            }
            String result = sb.toString();
        } catch (MalformedURLException e) {
            LOG.severe("Change relay status malformed URL " + e.toString());
        } catch (IOException e) {
            LOG.severe("Change relay status IOexception" + e.toString());
        }
    }

    @Override
    protected boolean canExecute(Command c) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    protected void onEvent(EventTemplate event) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public static Object getKeyFromValue(Map hm, Object value) {
        for (Object o : hm.keySet()) {
            if (hm.get(o).equals(value)) {
                return o;
            }
        }
        return null;
    }
}