Package it.freedomotic.plugins.x10.gateways

Source Code of it.freedomotic.plugins.x10.gateways.PMix35Gateway

/**
*
* Copyright (c) 2009-2013 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 it.freedomotic.plugins.x10.gateways;

import it.freedomotic.app.Freedomotic;
import it.freedomotic.events.ProtocolRead;
import it.freedomotic.plugins.x10.X10;
import it.freedomotic.plugins.x10.X10AbstractGateway;
import it.freedomotic.plugins.x10.X10Event;
import it.freedomotic.serial.SerialConnectionProvider;
import it.freedomotic.serial.SerialDataConsumer;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* An implementation of a reader/writer for an X10 transciever named Xannura
* Home PMIX35 You can find the technical manual at
* http://freedomotic.googlecode.com/files/PMIX35.pdf
*
* @author Enrico Nicoletti (enrico.nicoletti84@gmail.com)
*/
public final class PMix35Gateway implements X10AbstractGateway, SerialDataConsumer {

    private static SerialConnectionProvider usb = null;
    //PMIX strings for ack, nack and null messages
    private static final String PMIX_ACK = "$<9000!4A#".trim();
    private static final String PMIX_NACK = "$<9000?4A#".trim();
    private static final String PMIX_NULL = "$<900029#".trim();
    private String lastReceived = "";
    private X10Event x10Event = new X10Event();
    private X10 plugin;

    public PMix35Gateway(X10 plugin) {
        this.plugin = plugin;
        connect();
    }

    /**
     * Connection with the PMIX35 over serial port
     */
    @Override
    public void connect() {
        if (usb == null) {
            Properties config = new Properties();
            config.setProperty("hello-message", "$>9000PXD3#"); //hello message defined by pmix15 comm protocol
            config.setProperty("hello-reply", "$<9000VP"); //expected reply to hello-message starts with this string
            config.setProperty("polling-message", "$>9000RQCE#"); //$>9000RQcs# forces read data using this string
            //The computer always take the initiative to read, the PMIX35 is a passive gateway
            config.setProperty("polling-time", "1000"); //millisecs between reads.
            config.setProperty("port", "/dev/ttyUSB0");
            usb = new SerialConnectionProvider(config); //instantiating a new serial connection with the previous parameters
            usb.addListener(this);
            usb.connect();
            if (usb.isConnected()) {
                plugin.setDescription("Connected to " + usb.getPortName());
            } else {
                plugin.setDescription("Unable to connect to " + config.getProperty("port"));
                plugin.stop();
            }
        }
    }

    @Override
    public void disconnect() {
        if (usb != null) {
            usb.disconnect();
            if (!usb.isConnected()) {
                plugin.setDescription("Disconnected");
            }
        }
    }

    @Override
    public String send(String message) throws IOException {
        String reply = usb.send(message);
        return reply;
    }

    /**
     * Parse the PMIX35 readed line to find X10 standard codes
     *
     * @param readed
     * @return
     */
    @Override
    public String parseReaded(String readed) {

        //if nothing is readed. Likely the PMIX35 is no longer connected to usb
        if (readed.isEmpty()) {
            usb.disconnect();
            return "";
        }

        //if readed is a noise detection/network impedance value discard this line
        if (readed.contains(PMIX_NULL)
                || readed.contains(PMIX_ACK)
                || readed.contains(PMIX_NACK)) {
            return "";
        }

        //removing the prifix ($<9000) and the suffix (CS#)
        //CS is the checksum (2 characters)
        readed = readed.substring(6, readed.length() - 3);
        //it's a command echo
        if (readed.startsWith("LE")) {
            System.out.println(readed);
            return "";
        }

        //if the message is a network noise detection value
        if (readed.startsWith("ND")) {
            boolean isNoisy = (new Integer(readed.substring(2, 4)) == 1); //noise on the network
            //System.err.println("Powerline network is really noisy. Possible loose of data");
            //if the message is a network impedance value
            readed = readed.substring(4);
        } else if (readed.startsWith("NI")) {
            int impedance = new Integer(readed.substring(2, 6)); //Network inmpedance
            readed = readed.substring(6);
        }

        //check again for command echo as we can have ND00LE A01... or NI0000LE A01...
        if (readed.startsWith("LE")) {
            System.out.println(readed);
            return "";
        }

        //otherwise remains an X10 standard string (EG: A01 AON)
        readed = readed.substring(10).trim();
        return readed;
    }

    /**
     * A PMIX35 message is composed by a start string + the x10 message + a
     * checksum + PMIX end of line (the # character) For example: <ul> <li>
     * A01A01 AONAON -> $>9000LW A01A01 AONAON**# </ul> ** corresponds to the
     * checksum (2 characters). LW means line write in PMIX35 lingo
     *
     * @param the string to translate in PMIX35 format
     * @return the encoded string ready to be sent to the PMIX35
     */
    @Override
    public String composeMessage(String housecode, String address, String command) {
        //Adding the standard prefix
        String message =
                "$>9000LW "
                + housecode + address
                + housecode + address
                + " "
                + housecode + command
                + housecode + command;

        //Calculate the chacksum
        int sum = 0;
        for (int i = 0; i < message.length(); i++) {
            sum += message.charAt(i);
        }
        //we need only the last to char of the checksum
        String cs = Integer.toHexString(sum);
        cs = cs.substring(cs.length() - 2);
        cs = cs.toUpperCase();

        //Adding the end of line character and construction the whole encoded string
        return message + cs + "#\r\n";
    }

    @Override
    public String getName() {
        return "PMIX35";
    }

    @Override
    public void onDataAvailable(String readed) {
        String[] tokens = readed.split("#");
        for (int i = 0; i < tokens.length; i++) {
            String line = parseReaded(tokens[i] + "#");
            if (!line.isEmpty() && !line.equals(lastReceived)) {
                lastReceived = line;
                System.out.println(lastReceived);
                if (X10.isAnX10Address(line)) {
                    x10Event.setAddress(line);
                } else {
                    if (X10.isAnX10Command(line)) {
                        x10Event.setFunction(line);
                        if (x10Event.isEventComplete()) {
                            System.out.println("send x10 event " + x10Event);
                            x10Event.send();
                        }
                    }
                }
            }
        }
    }

    @Override
    public void read() {
        try {
            send("$>9000RQCE#");
        } catch (IOException ex) {
            Logger.getLogger(PMix35Gateway.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
TOP

Related Classes of it.freedomotic.plugins.x10.gateways.PMix35Gateway

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.