Добрый день, хочу поделиться опытом создания приложения, которое отслеживает замыкание контактов 7 и 8 на обычном китайском USB-COM переходнике (RTS – CTS) и если такое событие происходит, то отправляет мне на мэйл письмо.

Постановка задачи и выбор инструментов

Изначально цель была – сделать датчик протекания воды. Что потом делать с замыканием – по большому счёту неважно, но мне захотелось сделать отправку состояния на почту. Поскольку я учусь Java на JavaRush, то и инструмент был выбран соответствующий – IntelliJ Idea. Конечно, почта – это не смс, но для смс нужна работа с ком портом, а здесь мы освоим очень хороший инструмент для этого, и когда я разберусь с 3g модемом, то можно будет добавить немного информации, хотя её и так много в интернете.

Схема подключения к COM-порту

Итак, не будем заостряться на железячной части, рассмотрим сам разъём DB9F Контакт 5 – это земля, контакт 7 – это RTS – в нашей программе на нём всегда будет висеть 1 ( + 9 В относительно контакта 5), и контакт 8 – это вход – он подтянут 5килоомным резистором к 0 В. Надо сказать, что когда наша программа не запущена, то на 7 контакте будет напряжение -9 В, это надо учитывать, когда будете брать датчик разлива, на 8 контакт подать можно, но бывают устройства, которые горят от отрицательных напряжений.

Принцип работы программы

Итак, чтобы проверить, как наша программа будет работать, после её запуска замкнём контакт 7 на контакт 8, наша программа раз в секунду будет отслеживать такое событие и присылать письмо с текстом «Лужа», а потом разомкнём – и программа отошлёт письмо с текстом «Нет лужи».

Создание проекта в IntelliJ IDEA

Итак, чтобы установить JDK и IntelliJ Idea, выучить какие-то основы java, можно воспользоваться первыми уроками JavaRush.ru. Мы же начнём с создания нового проекта. Сразу оговорюсь, что если у вас уже открыт проект, то при создании нового проекта будет предложено открыть его в новом окне – очень удобно. (Когда-то я пробовал работать с eclipse, там все проекты открываются в одном окне). Дальше я привожу много картинок без описания – и так всё понятно. Замыкаем контакты и получаем письмо - 1 Замыкаем контакты и получаем письмо - 2 Замыкаем контакты и получаем письмо - 2 Замыкаем контакты и получаем письмо - 4 Замыкаем контакты и получаем письмо - 3 Замыкаем контакты и получаем письмо - 6Замыкаем контакты и получаем письмо - 4 Замыкаем контакты и получаем письмо - 8 Замыкаем контакты и получаем письмо - 5

Подключение библиотек через Maven

Вот начиная со следующей картинки очень интересно – я всегда видел этот мавен, но боялся что-то с ним сделать, а тут попробовал – и всё оказалось очень просто – если тебе нужна библиотека – ты просто вводишь её название, ищешь последнюю версию и скачиваешь. Смотрите. Мы скачиваем библиотеку http://habrahabr.ru/post/133766/ jSSC И библиотеку javax:mail – она я так понимаю была удалена из стандартного списка библиотек, но в мавене её легко скачать. Замыкаем контакты и получаем письмо - 6 Замыкаем контакты и получаем письмо - 11 Замыкаем контакты и получаем письмо - 7 Замыкаем контакты и получаем письмо - 13 Замыкаем контакты и получаем письмо - 8 Нажимаем OK и библиотеки добавились. Вуаля :) Замыкаем контакты и получаем письмо - 9

Код программы

Набираем текст

comRun.java

package ru.example.comTest.Test1;

import jssc.*;

import java.io.UnsupportedEncodingException;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;

/**
 * Created by ipolma on 8/12/2014.
 */

public class comRun {


    private static SerialPort serialPort;

    public static void main(String[] args) {


        String[] retPorts = SerialPortList.getPortNames();
        //for (String port: retPorts){System.out.println(port);}

        serialPort = new SerialPort(retPorts[1]);//"COM4"); указываем второй порт
        System.out.println(serialPort.getPortName());
        try {
            //Открываем порт
            if (serialPort.isOpened()) serialPort.closePort(); //Здесь бывает ситуация Busy, которую не обработаешь - только если ожидать
            serialPort.openPort();
            //Выставляем параметры
            serialPort.setParams(SerialPort.BAUDRATE_9600,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);
            //Включаем аппаратное управление потоком
            serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN |
                    SerialPort.FLOWCONTROL_RTSCTS_OUT);

            int tempData0 = 0;

            while(true){
                Thread.sleep(1000);
                int[] data = serialPort.getLinesStatus();//readString(event.getEventValue());
                //7 и 8 контакты замыкаются - 1010
                //разомкнуты                - 0010
                //7 и 6 контакты замыкаются - 0110
                //data[0] - 12 В на 8 (CTS)
                //data[1] - 12 В на 6 (DCE)
                //serialPort.setDTR(status); //Меняется напряжение только на 4 контакте - но и это хорошо
                //serialPort.setRTS(status); // На 7 не меняется- можно это использовать как выход +-7В.

                if (data[0] == 1){
                    tempData0 = 1;
                    sendEmail("Лужа");
                    System.out.println("1");
                }
                if (data[0] == 0 && tempData0 == 1){
                    tempData0 =0;
                    System.out.println("0");
                    sendEmail("Нет лужи");
                }
            }
        }
        catch (SerialPortException ex) {
            System.out.println(ex);
        }
        catch (InterruptedException ty){}

    }

    private static void sendEmail(String text){

        try {
            // Создаем адреса отправителя и прлучателя
            InternetAddress from = new InternetAddress("*****@yandex.ru", "From");
            InternetAddress to = new InternetAddress("****@****.ru", "To");
            // Далее создаем т.н. транспорт с определенными параметрами, который
            // будет "заниматься" отправкой сообщения
            Properties props = new Properties();
            // Тип протокола, адрес сервера и номер порта
            props.put("mail.transport.protocol", "smtp");
            props.put("mail.smtp.host", "smtp.yandex.ru");
            props.put("mail.smtp.port", "25");
            Session session = Session.getDefaultInstance(props);
            Transport transport = session.getTransport();
            // Теперь создаем сообщение
            MimeMessage message = new MimeMessage(session);
            message.setText(text, "utf-8");
            message.setFrom(from);
            message.setRecipient(Message.RecipientType.TO, to);
            message.setSubject("Тема", "utf-8");
            // При подключении указываем параметры для smtp сервера: логин и пароль
            transport.connect("*****@yandex.ru", "**Password***");
            transport.sendMessage(message, new Address[]{to});
            transport.close();
        } catch (UnsupportedEncodingException ex) {
            ex.printStackTrace();
        } catch (NoSuchProviderException ex) {
            ex.printStackTrace();
        } catch (MessagingException ex) {
            ex.printStackTrace();
        }
    }

}

Настройка SMTP и тестирование

Ставим существующие адреса и пароли (кстати, интересно, что в помощи на яндексе про смтп написано про 465 порт, а в интернете я нашёл 25 порт- и это оказалось верно). Запускаем на выполнение. Замыкаем контакты 7 и 8, через три секунды отпускаем 1 – контакты замкнуты, отсылается письмо «Лужа», 0 – контакты разомкнуты – отсылается письмо «Лужи нет» Замыкаем контакты и получаем письмо - 10 Вот что у меня в почте Замыкаем контакты и получаем письмо - 17 Замыкаем контакты и получаем письмо - 11 Замыкаем контакты и получаем письмо - 19

Создание JAR-файла

Теперь хочется иметь приложение. Здесь пока я изучал материал – я плакал – неужели надо создавать манифест файл, класспатч прописывать… страшное дело. У skipy всё это описано. Я чуть руки не опустил, но у меня на кухне в ящиках стола уже перевелись давно перфокарты, и у нас есть идея, поэтому делал jar архив я очень просто – смотрите. Замыкаем контакты и получаем письмо - 12 Замыкаем контакты и получаем письмо - 21 Замыкаем контакты и получаем письмо - 13 Ставим галочку Build on Make – после очередной компиляции в idea в папке out будет результат. Замыкаем контакты и получаем письмо - 14 Всё – jar в ауте, и настолько самостоятелен, что во всяком случае, в пределах машины копируется и запускается откуда угодно. Замыкаем контакты и получаем письмо - 15

Создание bat-файла для запуска

Но если его просто запустить, то письма отсылаться будут, а консоли не будет, и убить процесс можно только найдя такую запись в диспетчере задач. Замыкаем контакты и получаем письмо - 16 Переносим в другую папку, оттуда он тоже запускается, и делаем bat файл Замыкаем контакты и получаем письмо - 17 Замыкаем контакты и получаем письмо - 27 Запускаем батник Замыкаем контакты и получаем письмо - 18 Замыкаем контакты и получаем письмо - 29 Вот и консоль, а по Ctrl+C – запрос на выход. Замыкаем контакты и получаем письмо - 19 Замыкаем контакты и получаем письмо - 31

Создание EXE-файла с помощью Launch4j

Но если запустить jar два раза, то второй раз не удастся- ком порт будет занят. Поэтому желательно сделать сингл аппликэйшн. Ставим себе Launch4j, запускаем, выбираем аутпут файл – любое имя, должно быть exe в основном окошке, затем наш jar, выбираем консольный тип, минимальную версию 1.4.0 Замыкаем контакты и получаем письмо - 20 Замыкаем контакты и получаем письмо - 33 Замыкаем контакты и получаем письмо - 21 Замыкаем контакты и получаем письмо - 35 Указываем, что нам не надо много экземпляров Замыкаем контакты и получаем письмо - 22 Замыкаем контакты и получаем письмо - 37 Нажимаем на кнопку с шестерёнкой Замыкаем контакты и получаем письмо - 23 Нас спрашивают, где хранить временные файлы, мы отвечаем Замыкаем контакты и получаем письмо - 24 Замыкаем контакты и получаем письмо - 40 Гуд лак – всё готово. Запускаем экзешник. Замыкаем контакты и получаем письмо - 25 Правда, в диспетчере он будет всё равно исполняться под javaw Замыкаем контакты и получаем письмо - 26 Письма идут Замыкаем контакты и получаем письмо - 43 Такие дела, мне понравилась джава. PS. Вывод в консоль обрушивает программу через какое-то количество строк, поэтому если вдруг вы повторите такой алгоритм, то не забудьте отключить вывод в консоль.