Добрый день, хочу поделиться опытом создания приложения, которое отслеживает замыкание контактов 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. Вывод в консоль обрушивает программу через какое-то количество строк, поэтому если вдруг вы повторите такой алгоритм, то не забудьте отключить вывод в консоль.