Доброго дня, уважаемое сообщество.

Сегодня хочу поделиться с Вами опытом построения умного с использованием оборудования компании НооТехника, а если точнее, то реализации сценария «Хозяин дома». Что я под этим понимаю? Запуск особого «сценария», в момент прихода домой «хозяина». Под хозяином в данном случае понимаю самого себя, а сценарий состоит из включения источников света в зоне прихожей и декоративного освещения в других комнатах.

В качестве аппаратного обеспечения умного дома я выбрал оборудование компании Ноотехника.

Те, кто уже знаком с устройствами от Ноотехника и хочет сразу перейти к описанию реализации сценария, могут смело скроллить к разделу 2. Всем остальным предлагаю ознакомиться с кратким вступлением, дающим общее представление об устройстве умного дома от Ноотехника.

1. Вступление


В качестве аппаратного обеспечения моего умного дома я уже несколько лет использую оборудование компании Ноотехника. Ассортимент устройств достаточно широк для построения умного дома в рамках городской квартиры и постоянно расширяется. На данный момент имеются радио-выключатели разных конфигураций, силовые блоки – для подключения источников света и электроприборов, датчики движения, влажности и температуры, а также передатчики и приемники команд (для подключения к компьютеру). Есть еще т.н. Ethernet-шлюз, который также можно использовать для централизованного управления устройствами умного дома от компании Ноотехника.

На данный момент в своем умном доме я использую несколько 3-х кнопочных выключателей, порядка 10 силовых блоков, 2 датчика движения, а также передатчик сигналов (модели PC1116) силовым блокам и приемник (модели RX2164) сигналов от датчиков и выключателей.

В качестве элемента управления умным домом использую неттоп 3VI на базе процессора Intel ATOM D525 с ОС Debian 7 на борту. К нему подключены приемник и передатчик.

В качестве программного обеспечения для управления умным домом использую набор утилит под Linux от Олега Артамонова, который доступен на GitHub — github.com/olegart/noolite. Также на неттопе поднят веб-сервер и самописный веб-интерфейс для общения с устройствами умного дома.

Перед началом описания реализации сценария, пару слов о самих устройствах и что для чего предназначено:

  1. Силовые блоки (бывают разные, для поддержки различных нагрузок, начиная от 200 Вт и заканчивая несколькими КВт). Подключаются к сети переменного тока и предназначены для управления электроприборами (подключаются «в разрыв» между сетью и электроприбором);
  2. Радио-выключатели. Предназначены для:
    — отправки команд включения, выключения, изменения нагрузки (диммирования) на силовые блоки,
    — отправки команд на приемник RX2164 (подключенный к ПК);
  3. Датчики движения, температуры, влажности. Предназначены для отправки команд на силовые блоки или на приемник;
  4. Приемник сигналов RX2164. Предназначен для приема сигналов от датчиков или выключателей;
  5. Передатчик сигналов PC1116. Предназначен для отправки управляющих сигналов на силовые блоки.

Пример общей схемы взаимодействия компонентов приведен на рисунке 1.

Рисунок 1 – Общая схема взаимодействия компонентов

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

2. Постановка задачи


Необходимо реализовать включение источников света в зоне прихожей, а также декоративных источников света в зале и коридоре в момент, когда хозяин (т.е. ваш покорный слуга) возвращается домой.

На данном этапе хочу отметить несколько моментов, на которые необходимо обратить внимание на этапе решения задачи:

  1. Необходимо идентифицировать пришедшего (что это именно хозяин);
  2. Необходимо убедиться, что хозяин ПРИШЕЛ, а не просто оказался возле двери (например, чтобы проверить заперт ли замок);
  3. Необходимо убедиться, что хозяин ПРИШЕЛ, а не просто вышел из дома на пару минут и вернулся (встретить курьера, открыть дверь в тамбуре и т.п.).

3. Описание решения


Для решения задачи №1 было решено использовать смартфон хозяина как его (хозяина) идентификатор. Т.е. если смартфон подключен к домашнему WiFi-роутеру, значит хозяин дома. На DHCP-сервере роутера создана статическая запись соответствия IP-адреса МАС-адресу смартфона. Таким образом, смартфон всегда появляется в сети с одним и тем же IP-адресом.

Для решения задачи №2 используются два датчика движения Ноотехника модели РМ112 и приемник сигналов RX2164. Один из них установлен перед входной дверью в квартиру в тамбуре. Второй установлен внутри квартиры, прямо возле входной двери. Идея состоит в том, чтобы идентифицировать событие прихода в квартиру по последовательному срабатыванию датчиков в тамбуре и в квартире. Описание решения данной подзадачи приведено в разделе 4.

Для решения задачи №3 используется скрипт – «генератор статуса» (см. рисунок 3), который проверяет подключение смартфона хозяина к WiFi-роутеру каждую минуту и записывает текущий статус в файл. Логику в скрипте я настроил таким образом, чтобы он НЕ генерировал событие прихода домой хозяина, если время его отсутствия соста��ляет менее 20 минут (например, если хозяин вышел на пару минут). Конечно, этот порог можно настроить как угодно. Описание решения данной подзадачи приведено в разделе 5.

Кроме этого, необходимо нечто, что сможет связать все события с датчиков, и запустить скрипт, который в свою очередь проверит статус и в случае выполнения условий (т.е. прихода хозяина домой) включит источники света. Для решения данной задачи я выбрал программное обеспечение Simple Event Correlator, работающее под Linux и свободно распространяемое. Написал в дополнение к нему скрипт – «проверщик подключения смартфона» (см. рисунок 3). Описание решения данной подзадачи приведено в разделе 6.

Датчики движения РМ112 я установил как показано на рисунке 2.


Рисунок 2 – Схема расстановки датчиков движения РМ112

Места для установки датчиков, а также их чувствительность выбирались и настраивались таким образом, чтобы исключить ложные срабатывания.

Далее кратко опишу схему взаимодействия всех компонентов решения.

Приемник сигналов от датчиков Noolite подключен к неттопу (далее – ПК, см. рисунок 1). На ПК настроена запись сообщений, получаемых от датчиков, в лог файл в режиме реального времени (см. рисунок 3). Simple Event Correlator (далее — SEC) работает на ПК и читает лог файл (в который приходят события с датчиков). В SEC настроено правило, которое срабатывает в случае получения сигналов о наличии движения от датчика 1 (см. рисунок 2) и в течение не более чем 60 секунд следом за ним сигнала о наличии движения от датчика 2 (см. рисунок 2). При срабатывании этого правила запускается скрипт — проверщик, который проверяет статус хозяйского смартфона, читая информацию из файла статуса а также выполняя самостоятельные проверки (для уменьшения ложных срабатываний). В случае регистрации скриптом факта прихода хозяина домой, выполняется запуск сценарной программы включения света.

Также необходимо упомянуть о скрипте – генераторе статуса. Этот скрипт ежеминутно проверяет статус смартфона хозяина вне зависимости дома хозяин или нет и запускает внутренние счетчики в случае его (статуса) изменения. Одним словом – отслеживает статус смартфона.

Схема, поясняющая вышесказанное, приведена на рисунке 3.


Рисунок 3 – Блок-схема взаимодействия компонентов системы

4. Идентификация события прихода домой


В этом разделе я рассмотрю вопросы подключения и настройки датчиков движения PM112, а также настройки утилиты управления приемником RX2164.

Места для установки датчиков, а также их чувствительность выбирались и настраивались таким образом, чтобы исключить ложные срабатывания. Датчик №1 я установил над тумбой для обуви (см. рисунок 4) и настроил чувствительность так, чтобы он реагировал на движение на расстоянии около 50 см. (этому соответствует положение регулятора «чувствительность», как на рисунке 5 – чуть больше половины хода регулятора). Если сделать чувствительность больше – может реагировать на проходящих мимо соседей, а если засунуть под тумбу, то банально его могут заставить обувью домочадцы. Настройку освещенности установил в положение «Вкл» — крайнее нижнее. Хотя другие настройки освещенности обеспечивают энергосбережение (работает-то от батареек), но при других настройках освещенности мне не удалось добиться стабильного срабатывания. Скорее всего тому виной не очень обильное освещение в местах установки датчиков. Время включения я установил на 5 секунд. Для меня этот параметр не очень важен, т.к. мои датчики привязаны к приемнику, подключенному к ПК и мне нужно получать только события регистрации движения в зоне работы датчика.

Второй датчик я установил над входной дверью со стороны квартиры (см. рисунок 6). Входная дверь находится в небольшой нише, поэтому над ней есть очень удобное место для закрепления датчика. Крепил на саморезы. Порог чувствительности установил аналогичный порогу датчика №1, чтобы срабатывал на движение примерно на расстоянии 50см. Если больше, то будет много ложных срабатываний когда кто-нибудь лезет в шкаф за одеждой или на домашнюю живность.


Рисунок 4 – Установка датчика в тамбурной зоне


Рисунок 5 – Настройка датчика движения


Рисунок 6 – Установка датчика в зоне прихожей

Для получения сообщений от датчиков движения я использую комплект утилит, работающих под операционной системой Linux. В моем случае это Debian 7.

Данный набор утилит разработан Олегом Артамоновым и доступен на GitHub. Установка комплекта утилит неплохо описана самим автором, поэтому на ней я останавливаться не буду. Только отмечу, что для ее выполнения Вам таки понадобятся знания Linux и в особенности понимание устройства скриптов /etc/init.d/.

Первым делом нужно «привязать» датчики движения РМ112 к приемнику RX2164. Для этого необходимо выполнить следующие действия:

  • включить режим привязки на самом датчике, один раз нажав кнопку «привязка/отвязка» на задней стенке датчика;
  • на ПК выполнить команду в консоли:

# nooliterxcfg –bind <номер канала от 1 до 64>

Данную процедуру нужно выполнить для каждого датчика. В моем случае их два и привязаны они к каналам 2 и 3, поэтому:

# nooliterxcfg –bind 2
# nooliterxcfg –bind 3

Для того, чтобы утилита nooliterx работала в фоне, нужно стартовать ее с помощью скрипта /etc/init.d/nooliterx. Этот скрипт есть на github в месте с утилитами, однако под моим Debian он не заработал, поэтому я немного его модифицировал. В итоге получилось следующее:

#!/bin/sh
# nooliterx     Starts and stops the NooLite RX1164 receiver daemon
# chkconfig: 2345 55 25
# description: NooLite RX1164 smart home wireless receiver daemon
# Source function library.
. /lib/lsb/init-functions
#. /etc/rc.d/init.d/functions
nooliterx="/usr/local/bin/nooliterx"
prog=`basename $nooliterx`
lockfile="/var/lock/subsys/nooliterx"
pidfile="/var/run/$prog.pid"
start() {
    [ -x $nooliterx ] || exit 5
    echo -n "Starting $prog: "
    start-stop-daemon --start --exec $nooliterx --make-pidfile --pidfile $pidfile --background
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}
stop() {
    echo -n "Stopping $prog: "
    killproc -p $pidfile $prog
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
restart() {
    stop
    start
}
case "$1" in
    start)
        $1
        ;;
    stop)
        $1
        ;;
    restart)
        $1
        ;;
    *)
        echo $"Usage: $0 {start|stop|restart}"
        exit 2
esac

По-умолчанию, nooliterx пишет сообщения о срабатывании датчиков движения в syslog. Это очень удобно. Для того, чтобы сообщения от датчиков попадали в отдельный файл (который будет анализироваться SEC) я настроил перенаправление в syslog-ng, установленном на ПК. Для этого добавил следующие строчки в сответствующие разделы файла /etc/syslog-ng/syslog-ng.conf:

destination sec_log { file("/var/log/sec.log"); };
filter motion_sens { program("nooliterx.*"); };
log { source(s_src); filter(motion_sens); destination(sec_log); };

Перезапускаем syslog-ng для применения изменений:

# /etc/init.d/syslog-ng restart

Для работы в фоне nooliterx запускается следующим образом:

# /etc/init.d/nooliterx start

Для проверки работы настроенной схемы создаем движение вблизи датчиков и смотрим на сообщения, приходящие в файл /var/log/sec.log. Они должны иметь примерно следующий вид:

Dec 19 08:40:55 vmon nooliterx[23022]: Received: status 135, channel 2, command 25, format 1, data 1 0 0 0
Dec 19 08:41:19 vmon nooliterx[23022]: Received: status 8, channel 3, command 25, format 1, data 1 0 0 0
Dec 19 08:41:22 vmon nooliterx[23022]: Received: status 137, channel 3, command 25, format 1, data 1 0 0 0

Причем, при каждом событии фиксации движения должно появляться два сообщения в лог файле т.к. в связи с конструктивной особенностью датчиков они отправляют два сигнала на каждое свое срабатывание. Это сделано для того, чтобы гарантировать доставку сообщения, поскольку связь является однонаправленной и в ОЧЕНЬ редких случаях сообщения от датчика до приемника могут теряться.

5. Генератор статуса


Скрипт – «генератор статуса» проверяет подключение смартфона к домашней WiFi сети каждую минуту и записывает текущий статус в файл. Проверка осуществляется очень просто – посредством посылки ICMP пакетов на IP адрес смартфона. Блок схема логики, согласно которой скрипт вычисляет статус приведена на рисунке 7.

На основе данных, которые записывает скрипт в статус файл производится корреляция при срабатывании датчиков движения и принимается решение о запуске сценария (это делает скрипт – проверщик, который описан в разделе 6).

Скрипт отрабатывает каждую минуту и обновляет информацию в статус файле, а также дописывает информацию о статусе с текущей временной меткой в лог файл.
Информация в статус файле состоит из:

  • текущего статуса смартфона, который может принимать значения arrived, athome, away;
  • наименования счетчика времени – «ушел» или «дома»;
  • значение счетчика (соответствует кол-ву минут).

Статус «athome» свидетельствует о том, что смартфон дома, подключен к сети. Статус «away», соответственно, говорит об отсутствии смартфона дома (подключения к сети). Статус «arrived» появляется когда смартфон только появился в сети и еще не была запущена сценарная программа. Как только сценарий включения света сработал, статус меняется на «athome». Это сделано для исключения множественных срабатываний.

Отсутствием хозяина дома считается отсутствие подключения смартфона к сети в течение более 20 минут. Такая логика настроена для фильтрации ложных срабатываний (если, например, смартфон кратковременно отключился от сети) и для того, чтобы сценарий не активировался, если хозяин кратковременно отлучался из дома. Это условие предусмотрено в блок-схеме. И для этой цели введены разные типы счетчиков – «ушел» и «дома». При отсутствии смартфона в сети, сохраняется статус «athome» и начинается отсчет счетчика «ушел» при сохранении статуса «athome». Как только значение счетчика превышает 20, статус меняется на «away».


Рисунок 7 – Блок-схема работы «генератора статуса»

Ниже приведен полный листинг скрипта «генератор статуса».

#! /bin/sh
dir=/usr/local/smarthome/imhome
phone_ip=$1
stat_file="$dir/status"
log_file="$dir/log_status"
dt=`date`
if ping -c 5 $phone_ip > /dev/null
then
   if grep "athome" $stat_file
   then
      count=$(($(cat $stat_file|grep pingok | awk -F "_" '{print $2}')+1))
      stat="athome"
      png="pingok_"
   elif grep "arrived" $stat_file
   then
      count=$(($(cat $stat_file|grep pingok | awk -F "_" '{print $2}')+1))
      stat="arrived"
      png="pingok_"
   else
      count="1"
      stat="arrived"
      png="pingok_"
   fi
else
   if grep "athome" $stat_file
   then
      if grep pingnok $stat_file
      then
         count=$(($(cat $stat_file|grep pingnok | awk -F "_" '{print $2}')+1))
         if [ "$count" -gt 20 ]
         then
            count="1"
            stat="away"
            png="pingnok_"
         else
            stat="athome"
            png="pingnok_"
         fi
      else
         count="1"
         stat="athome"
         png="pingnok_"
      fi
   elif grep "away" $stat_file
   then
      count=$(($(cat $stat_file|grep pingnok | awk -F "_" '{print $2}')+1))
      stat="away"
      png="pingnok_"
   else
      count="1"
      stat="away"
      png="pingnok_"
   fi
fi
printf "$stat\n$png$count\n" > $stat_file
printf "$dt $stat $png$count\n" >> $log_file

6. SEC. Корреляция событий и запуск сценария


Запуск сценария включения источников света должен выполняться при следующих условиях:

  1. Зафиксировано движение датчиком 1;
  2. Не позднее чем через 60 сек после события 1 зафиксировано движение датчиком 2;
  3. Смартфон хозяина подключился к сети WiFi в течение временного окна длительностью 1 минута.

Задачи 1 и 2 решает SEC. Решение задачи 3, а также запуск сценария выполняет скрипт – «проверщик подключения смартфона».

Я не буду подробно описывать установку и первичную настройку SEC т.к. в сети есть достаточно материалов и подробный MAN по этой утилите. В моем случае SEC настроен на чтение файла /var/log/sec.log т.к. в этот файл направляются события, приходящие от датчиков Noolite.

Конфигурационные файлы SEC приведены ниже. Файл /etc/default/sec (содержит основные настройки – конфигурационный файл с описанием правил корреляции в параметре “conf”, анализируемый лог файл в параметре “input”, syslog facility в который пишутся события самого SEC в параметре “detach”):

#Defaults for sec
RUN_DAEMON="yes"
DAEMON_ARGS="-conf=/etc/sec.conf -input=/var/log/sec.log -pid=/var/run/sec.pid -detach -syslog=local6"

Файл /etc/sec.conf с описанием правила корреляции, которое выполняет запуск скрипта – проверщика в случае фиксирования движения сначала датчиком 1, а потом датчиком 2 в течение 1 минуты:

type=PairWithWindow
ptype=RegExp
pattern=\w+\s+\d+\s+\d+\:\d+\:\d+\s+\w+\s+nooliterx\S+\s+Received\:\s+status\s+\d+,\s+channel\s+3,\s+command\s+25.*
desc=Motion sensor outside front door triggered
action=logonly
ptype2=RegExp
pattern2=\w+\s+\d+\s+\d+\:\d+\:\d+\s+\w+\s+nooliterx\S+\s+Received\:\s+status\s+\d+,\s+channel\s+2,\s+command\s+25.*
desc2=Motion sensor by the front door inside the flat triggered
action2=shellcmd (/usr/local/smarthome/imhome/check_phone.sh 192.168.22.155); write /usr/local/smarthome/imhome/test_corr_info %.year-%.mon-%.mday_%.%.hmsstr someone came 
window=60

Как видно, правило ищет события срабатывания датчиков по регулярным выражениям, которые записываются в параметрах «pattern».

При выполнении условий SEC запускается скрипт /usr/local/smarthome/imhome/check_phone.sh и передает ему IP адрес смартфона 192.168.22.155 в качестве аргумента.

Скрипт, в свою очередь, проверяет доступность смартфона (посредством отправки ICMP пакетов) и, в случае успеха, проверяет текущий статус смартфона в файле статуса (создаваемом скриптом – генератором статуса). Если значение статуса «away» или «arrived», то запускает сценарий включения источников света и перезаписывает значение статуса в файле статуса на «athome». Блок-схема работы скрипта приведена на рисунке 8.


Рисунок 8 – Блок схема работы скрипта – проверщика

Ниже приведен полный листинг скрипта. В качестве сценарной программы я выполняю включение 4 источников света с помощью утилиты noolitepc а также отправляю сообщение электронной почты самому себе (это было сделано с целью упрощения отладки на период тестирования). Между включениями источников света сделана секундная пауза. Когда команды следуют без нее, то не всегда долетают до силовых блоков.

#! /bin/sh
dir="/usr/local/smarthome/imhome"
phone_ip=$1
stat_file="$dir/status"
log_file="$dir/log_status"
dt=`date`
noolite="/usr/local/bin/noolitepc"
a=1
MAIL="$dir/mail.letter"
while [ "$a" -lt 10 ]
do
   if ping -c 2 $phone_ip > /dev/null
   then
      if grep 'arrived\|away' $stat_file
      then
         printf "$dt $phone_ip has come home. Welcome!\n" >> $log_file
         printf "Subject: Welcome home Boss!\nThe exact time is $dt\n" > $MAIL
         /usr/sbin/ssmtp test_email@gmail.com < $MAIL
         $noolite --on 3
         sleep 1
         $noolite --on 2
         sleep 1
         $noolite --on 6
         sleep 1
         $noolite --on 8
         printf "athome\npingok_1\n" > $stat_file
      fi
      break
   fi
   a=$((a+1))
done

Как видно, скрипт выполняет несколько циклов проверки (с помощью цикла while). Это сделано для того, чтобы гарантировать запуск сценария в том случае, если смартфон не успел подключиться к WiFi в момент срабатывания датчиков. Как показало тестирование, такое изредка бывает.

7. Заключение


В итоге у меня получилась система, которая может запускать любые сценарные программы в случае, регистрации прихода домой определенного человека. Сценарием может быть не только включение освещения, но и все, на что хватит фантазии. Например, можно включать музыкальный фон, делать фото пришедшего (с помощью IP камеры) и многое другое.

Коррелятор SEC следит за приходом домой кого-либо (анализируя события от датчиков Noolite), а дальше передает данные скрипту для проверки – кто именно пришел домой. А это значит, что можно настраивать разные программы для разных домочадцев. Передавая в скрипт IP адреса разных смартфонов и добавив соответствующие условия.

Отдельное БОЛЬШОЕ СПАСИБО хочу сказать компании Ноо��ехника за предоставленные для реализации этой системы датчики движения РМ112 и приемник RX2164.