Как подружить OpenHAB и Arduino

Мы все хотим сделать жизнь лучше, добавить в наш дом технические новинки, автоматизировать его и сделать более безопасным. Зачастую эти желания превращаются в движение по граблям. Известно, что фирменные системы дороги и часто не совместимы друг с другом, а создание своего решения по силам не каждому профессионалу. Что же делать, как найти простое решение доступное любителям, но и интересное профессионалам?

Arduino — простой электронный конструктор, который пользуется заслуженным уважением у любителей, говорят, что его недолюбливают профессионалы, хотя тайком используют в своих жутких экспериментах. В чём секрет его популярности, как воспользоваться ей для решения нашей задачи?

Arduino подходит для локального контроля и управления в доме, в сети есть масса проектов для этого — отлично, но недостаточно, ведь нужно мыслить глобально! Нам нужен выход в сеть и мобильный интерфейс!

Хорошо, что благодаря этой статье мы уже знакомы с OpenHAB — платформой с открытым исходным кодом, объединяющей большое количество устройства с разными протоколами в единую сеть. OpenHAB реализован на Java, поэтому работает в различных ОС, его можно запустить на одноплатном компьютере и даже роутере, в нём есть мобильный и Web интерфейс. Звучит как хороший набор заклинаний против наших, надоевших уже граблей, проверим?

Вначале установим OpenHAB, откроем страницу загрузки, скачаем Runtime core и Demo setup, распакуем их в C:\openhab. При распаковке Demo setup разрешим замену файла README.txt. Если на компьютере отсутствует Java (проверим командой java –version), то инсталлируем ее в соответствии с инструкцией.

Теперь запустим OpenHAB, выполнив C:\openhab\start.bat, подождём немного и откроем Web интерфейсlocalhost:8080/openhab.app?sitemap=demo
(если нам потребуется остановить OpenHAB — нажмём Ctl+C или закроем консоль программы)

image

Работает! Продолжим. Наша цель поиск простого решения, поэтому начнём с экспериментов. В одном из комментариев к статье предлагалось подключить контроллер к OpenHub через последовательный порт использовав Serial-Binding. Вполне интересное решение, попробуем его реализовать.

Для установки дополнения открываем страницу загрузки, качаем Addons, распаковываем org.openhab.binding.serial-1.6.1.jar (версия плагина может отличаться) в папку C:\openhab\addons. При желании читаем документацию.

Так как отладка взаимодействия с реальным устройством обычно доставляет немало хлопот, попробуем сначала отправить команды через терминал, соединив его с OpenHAB через эмулятор нуль-модемного кабеля.

Качаем и устанавливаем эмулятор com0com, запускаем утилиту image Setup из меню программы и видим, что при установке уже создана виртуальная пара последовательных портов — у меня это COM35 + COM36. Будем использовать их в нашей работе.

image

В качестве терминала я использовал Hercules SETUP utility, это бесплатная программа позволяющая выбрать порты с большими номерами и ввести несколько команд, отправляя их нажатием соответствующей кнопки. Скачиваем её, запускаем hercules_3-2-8.exe, переходим на вкладку “Serial”, выбираем второй порт виртуальной пары (у меня это COM36) и вводим следующие настройки – скорость 9600, 8 бит, 1 стоповый бит, нет контроля четности. Открываем порт.



Теперь нужно сконфигурировать openHAB, для этого воспользуемся его дизайнером. Откроем страницу загрузки, скачаем openHAB Designer и распакуем его в папку C:\openhab\designer, запустим C:\openhab\designer\openHAB-Designer.exe и укажем папку, в которой лежит конфигурация — C:\openhab\configurations.



Сначала создадим элемент (item) и свяжем его с первым в виртуальной паре последовательным портом (у меня это COM35). Для этого добавим следующий код в конец файла demo.items, после чего щёлкнем правой кнопкой мыши в окне редактора и скомандуем “Save”, вместо этого можно просто нажать ctl+S.

String Serial_string		"Текст [%s]" { serial="COM35" }



Для тестирования пропишем правило, которое каждую минуту будет отправлять команду созданному элементу. Для этого добавим следующий код в конец файла demo.rules после чего сохраним его.

rule "Test serial string"
when
    System started or
    Time cron "0 * * * * ?" 
then
  Serial_string.sendCommand("Test") 
end



Если OpenHAB запущен, мы почти сразу начнём принимать текст команды в терминальной программе, а в консоли увидим отчёт о её прохождении:



Попробуем теперь отправить команды в OpenHAB. Введём в терминале, в первое поле панели “Send” текст “ON_1”, а во второе “OFF_1”. Нажмём первую кнопку “Send”, затем вторую. В результате этого в консоли появляются следующие сообщения:



Для того, чтобы наши усилия не пропали даром, создадим правило которое будет обрабатывать наши команды, Для этого добавим следующий код в конец файла demo.rules и сохраним его.

rule "Serial control"
when
	Item Serial_string received update
then
	if(Serial_string.state=="ON_1")  sendCommand(Light_FF_Corridor_Ceiling, ON)
	if(Serial_string.state=="OFF_1") sendCommand(Light_FF_Corridor_Ceiling, OFF)
	if(Serial_string.state=="ON_2")  sendCommand(Light_GF_Kitchen_Ceiling, ON)
	if(Serial_string.state=="OFF_2") sendCommand(Light_GF_Kitchen_Ceiling, OFF)
end

Откроем WEB интерфейс, щёлкнем по пункту “First Floor” затем по пункту “Corridor” или скопируем в браузер ссылку: localhost:8080/openhab.app?sitemap=demo#_FF_Corridor, отправим текст “ON_1”, а потом OFF_1” из терминала. Проконтролируем выключатель в WEB приложении, его состояние должно изменяться.



Теперь нажмём “Home”, выберем пункт “Ground Floor” затем пункт “Kitchen” или скопируем в браузер ссылку: localhost:8080/openhab.app?sitemap=demo#_GF_Kitchen, отправим текст “ON_2”, а затем “OFF_2” из терминала. Проконтролируем выключатель в WEB приложении, его состояние также должно изменяться.



Результат нашего эксперимента можно наблюдать в консоли приложения, в которой появятся следующие сообщения:



На компьютере всё работает, пора подключаться к реальному миру!

В большинство плат Arduino уже встроен переходник с COM порта на USB, поэтому у нас не возникнет вопросов с присоединением к компьютеру или ноутбуку. Из подручных средств соберём макет, для этого нам понадобится контроллер Arduino, макетная плата, провода, кнопка, светодиод, резисторы 10кОм и 1кОм.



В сети достаточно инструкций и примеров, поэтому не нужно подробно описывать процесс установки и работы в среде разработки для Arduino. Перейдём сразу к созданию простого скетча, который будет обрабатывать нажатие кнопки и отправлять текстовые команды через последовательный порт. Для того, чтобы избежать ложной отправки команд, добавим в скетч нехитрую защиту от дребезга контактов.

Откроем редактор, добавим в него следующий код и сохраним скетч в файле btn.ino.

// задаем константы
const int buttonPin = 2;     // номер входа, подключенный к кнопке
const int ledPin =  13;      // номер выхода светодиода

// переменные
int buttonState = 3;         // переменная для хранения состояния кнопки
int buttonCnt = 0;           // переменная для защиты от дребезга кнопки

void setup() {
  // инициализируем пин, подключенный к светодиоду, как выход
  pinMode(ledPin, OUTPUT);     
  // инициализируем пин, подключенный к кнопке, как вход
  pinMode(buttonPin, INPUT); 
  // настраиваем последовательный порт
  Serial.begin(9600);  
}
 
void loop(){
  // обработка дребезга кнопки
  delay(1);
  if (buttonState != digitalRead(buttonPin)) buttonCnt++; else buttonCnt = 0;
  if (buttonCnt > 100)
  {
   // считываем значения с входа кнопки
    buttonState = digitalRead(buttonPin);
    buttonCnt = 0;
  // проверяем нажата ли кнопка
  // если нажата, то buttonState будет LOW:
    if (buttonState == LOW) {   
      // включаем светодиод   
      digitalWrite(ledPin, HIGH); 
      // отправляем команду
      Serial.print("ON_1");
    } else {
      // выключаем светодиод
      digitalWrite(ledPin, LOW);
      // отправляем команду
      Serial.print("OFF_1");
    }
  }
}



Компилируем и загружаем скетч в Arduino, открываем монитор порта, выбираем скорость 9600 и пробуем нажать кнопку на плате. В результате мы можем наблюдать получение команд:



Теперь закроем монитор порта и настроим связь OpenHAB с контроллером, для этого отредактируем настройки нашего элемента (в моём случае нужно поменять значение на COM18 так как USB переходник Arduino встал на этот порт).

String Serial_string		"Текст [%s]" { serial="COM18" }

В завершении проконтролируем прохождение команд при помощи консоли и WEB интерфейса.

Что мы получили в результате нашей работы:

1 установили, настроили OpenHAB, научились добавлять элементы (item) и автоматизировать обработку при помощи правил (rule);
2 научились тестировать обмен при помощи программных средств. Эти инструменты помогут в дальнейшем при поиске неисправностей и в постановке собственных экспериментов;
3 сделали простейший скетч для Arduino, подключили его к OpenHAB, создали правило обрабатывающее текстовые команды, протестировали возможность управления через последовательный порт.

Выводы:

Отправка команд в текстовом виде обычное дело в практике Arduino, обработку таких команд можно реализовать в OpenHAB поэтому такой способ взаимодействия заслуживает внимания и обсуждения.

Недостатком полученного решения является то, что команды ничем не разделены между собой кроме паузы, это может приводить к их “слипанию” и ненадёжной обработке. Для решения этой проблемы необходимо доработать скетч и правило обработки команд либо внести изменения в модуль Serial-Binding.

Многие назовут такой вариант взаимодействия с OpenHAB любительским, поэтому прежде чем продолжать работу над ним попробуем связать OpenHAB и Arduino через протокол Modbus.

Об этом в следующих публикациях:
Arduino & Modbus habrahabr.ru/post/249043
Arduino & OpenHAB habrahabr.ru/post/252555
Открытый контроллер умного дома на базе Arduino vk.com/myremoter
  • +18
  • 48,1k
  • 8
Поделиться публикацией
Похожие публикации
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 8
  • 0
    Спасибо за статью.
    В будущем хотелось-бы примеров с использованием MQTT (если можно), т.к. есть интересующиеся, желающие прикрутить OpenHAB к нашему модулю.
    • 0
      использовал https://github.com/VaclavSynacek/RF24SN для связи через NRF
      • 0
        Вот gist.github.com/belovictor/76e696c06b7c239447ea скетч для CC3200 Launchpad как раз для работы с openHAB по MQTT. На Arduino будет всё то же самое (ну только библиотеки сетевые по другому могут называться). На стороне openHAB всё настраивается по документации на mqtt binding — github.com/openhab/openhab/wiki/MQTT-Binding
        Смотреть раздел «Event Bus Binding Configuration», чтобы на каждый item не прописывать конфигурацию mqtt.
      • 0
        С последовательным портом в linux главное достоинство — драйвер есть в операционной системе и не требует установки
        • 0
          // если нажата, то buttonState будет LOW:

          Почему не наоборот?
          • 0
            На схеме один из выводов кнопки подключён к земле, а второй ко входу контроллера и через подтягивающий резистор 10 кОм к питанию, кнопка имеет нормально разомкнутые контакты, так что при нажатии кнопки вход контроллера замыкается на землю, что соответствует логическому 0 (LOW).
            • 0
              Ну да, а что-то поменяется, если резистор переставить к земле, так чтоб при нажатии кнопки вход контроллера замыкался на HIGH? Так вроде логичнее
          • 0
            А как слать команды с OpenHAB на устройство через COM порт?
            Я ничего умнее не придумал как писать правила типа:
            rule "Send Switch CMD"
            	when	
            		Item MySwitch received command
            	then
            		MyCOMString.sendCommand("Switch_"+MySwitch.state)
            end

            Но как-то это напряжно для каждого итема писать правило. Или по другому никак?

            И второй вопрос: в документации биндинга сериал порта (https://github.com/openhab/openhab/wiki/Serial-Binding) есть такой пример:
            
            Switch HardwareButton     "Bell"               (Entrance)      { serial="/dev/ttyS0" }
            String AVR                "Surround System"    (Multimedia)    { serial="/dev/ttyS1@115200" } 
            Number Temperature        "My Temp. Sensor"    (Weather)       { serial="/dev/ttyS1@115200,REGEX(ID:2.*,T:([0-9.]*))" } 
            

            Как я понимаю можно напрямую слать команды итемам? Например итем Temperature должен обновится если сработает регулярка?

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое