5 февраля 2014 г.

Управление и оповещение через jabber в openHAB

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

Я решил оповещения сделать на основе jabber, тем более, что данный вариант позволяет даже управлять openHABом из jabber. Создаем учетную запись (xmpp или jabber). Ищем секцию xmpp в openhab.cfg. Прописываем сервер, логин, пароль.
Отправляем команду help:

(15:22:48) I: help
(15:22:49) my****@jabber.org: Usage: 
update ⟨item⟩ ⟨state⟩ - sends a status update for an item
send ⟨item⟩ ⟨command⟩ - sends a command for an item
status ⟨item⟩ - shows the current status of an item
items [⟨pattern⟩] - lists names and types of all items matching the pattern
say ⟨sentence to say⟩ - Says a message through TTS on the host machine
⟩ ⟨script to execute⟩ - Executes a script


Теперь разберемся, как нам послать сообщение о смене статуса открытого замка. Для этого просто создадим новое правило в home.rules:

rule "Door Check Lock Send"
when
        Item Main_Door_Lock changed
then
        if(Main_Door_Lock.state==1)
        {
            sendXMPP("jabber@jabber.org", "Замок двери открыт!")
        }
        else if(Main_Door_Lock.state==0)
        {
            sendXMPP("jabber@jabber.org", "Замок двери закрыт!")
        }
        else{
            sendXMPP("jabber@jabber.org", "Неполадки с датчиком замка двери!")
        }
end


Очень помогает в написании правил функция авто-дополнения в дизайнере (Ctrl+Space), ибо документация по этому поводу хромает.

Поэкспериментировав понимаем, что время отклика оставляет желать лучшего. Смотрим лог owfs - датчик опрашивается openHAB'ом раз в минуту - это как раз настройка в openHAB. К сожалению на данный момент время обновления едино для всех датчиков 1-wire в openHAB. Поэтому ничего не остается, как сменить частоту обновления хотя бы на раз в 10 секунд.

Кеш owfs для датчиков по умолчанию 15 секунд. Поэтому, чтобы получать свежие значения, надо изменить его на 10 секунд. Пропишем в owfs.conf:
timeout_volatile = 10
#error_print = 1
error_print = 3
error_level = 2

error_print = 3 обозначает подавление логов - при опросе раз в 10 секунд из слишком много.

Протестировав я понял, что и 10 секунд слишком много. Но дальше увеличивать частоту опросов всех датчиков накладно. И вообще неплохо бы использовать unchached значения из owfs для датчиков, а кеш использовать только для датчиков, данные которых не критичны в времени опроса - например, датчики температуры. Но в openHAB пока с этим проблемы. Поэтому будем использовать небольшой хак. Для датчиков мы будем использовать exec binding и получать данные с файловой системы. Формат запроса:

in:  exec:"<[<commandline execute="" to="">:<refreshintervalinmilliseconds>:<transformationrule>]"

items:

Number Main_Door_Lock "Замок в двери C: [MAP(ru.map):%s]"<door>(Doors) { exec="<[/bin/cat /mnt/1wire/uncached/12.A214B2000000/sensed.A:5000:REGEX((.*?))]" }

В принципе, тут можно использовать и Contact.
Результат срабатывания правила:





Последний штрих - теперь нам надо настроить запуск приложения файловой системы owfs, потому что мы с него получаем данные. (Проверьте, что у вас запускается при старте в директориях rc.d).
# update-rc.d owfs defaults 30

Не забудьте выставить очередь запуска после owserver (у меня, как видно 30, а у owserver 20)!

4 февраля 2014 г.

Датчик открытого замка\двери\окна на 1-wire и openHAB

После небольшого перерыва на софт вновь перейду к железной стороне. Следующим устройством в сети мне надо сделать датчик открытого замка. Если вы помните, мы использовали электронную метку ds2401 для определения наличия датчика в сети. Как мы убедились, а умные люди нам подсказали - это работает слишком медленно. Поэтому мы будем использовать не определение датчика в сети, а сигналы от датчика-ключа ds2406p (такую микросехму я нашел, можно использовать и другие). Заодно мы сделаем и датчик открытой двери, ибо в таком исполнении у микросхемы два канала.

DS2406P универсальный элемент стандарта 1-Wire-net. Она содержит два независимых транзисторных ключа, с током потребления до 50 мА на предельном коммутируемом напряжении +13 В (для канала А) и до 8 мА на предельном коммутируемом напряжении +6 В (для канала B). DS2406P может быть использована также для контроля двух независимых датчиков дискретных сигналов типа "сухой контакт". (с).

Изучаем схему с сайта http://www.benuks.ru/



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

Освоим технологию создания плат (типа продинутый ЛУТ), мне понравилось вот это видео (пришлось даже ламинатор купить):



Единственно, я заменил самоклейку на фотобумагу. Но с ней у меня ничего не вышло, в итоге я взял лист от тонкого глянцевого журнала. Процесс травления не показан, ну можно поискать, или вот он:



Качаем архив со схемами в формате layout4. Находим там схему и печатаем на листе  тонкого глянцевого журнала, прогоняем результат с ламинатором.



То, что получилось у меня после печати и прогона в ламинаторе (160 градусов Цельсия):



Травим, получаем (снизу артефакты от первой печати с фотобумагой, сверху - плохой журнальный лист - тонер отскочил от него - подкрасил маркером):



Моем (бензин или ацетон) и сверлим отверстия (я собрал мини дрель - держатель в сборе в радио магазине, двигатель от детской машины).



Для покупки-сбора инструмента, освоение технологий, ушло пару-тройку рабочих недель. Цанговый патрон брал в местном радио-магазине, сверла здесь. Отличные сверла, рекомендую. Лудим, паяем плату.






Обратите внимание - в схеме надо делать перемычку для подачи 5 вольт на ds2406. Далее, я подпаял разъем rj11 и подключил к нашей сети 1wire . Заходим в директорию /mnt/1wire и смотрим - у нас должен появиться новый датчик. Подключив геркон к выводу "земля" и А (или B), а магнит приклеив к замку - получаем датчик закрытого\открытого замка:
root@truck:/mnt/1wire/12.***4B2000000# cat sensed.A
0
root@truck:/mnt/1wire/12.***4B2000000# cat sensed.B
1

B - можно использовать тут же, например, для датчика закрытой двери.

Стабилизатор с 18 на 12 вольт я впаивать не стал - в данном случае нам 12 вольт не нужно.

OpenHAB

Теперь нам надо показания датчиков открытия отобразить в OpenHAB. Я пытался использовать стандартный Contact item. Но по-видимому он еще не работает с 1wire. Поэтому пришлось прописать показания открытого замка как Number.

/* Active Group */
Group:Number:SUM        Doors   "Двери [открыто: %d]"     (All)

/* Contacts */

Number  Main_Door      "Входная дверь: [MAP(ru.map):%s]"       <door>  (Doors) { onewire="12.A234B4000000#sensed.B" }
Number  Main_Door_Lock "Замок в двери: [MAP(ru.map):%s]"        <door>  (Doors) { onewire="12.A234B4000000#sensed.A" }

1 - открытая дверь/замок, 0 - закрытая. Группа Doors (привет поклонникам Джима :) ) - показывает суммарное значение показаний item в группе - соответственно, количество открытых дверей.
ru.map пишем по аналогу en.map. В sitemap выводим просто группу.

Так как doors у нас через number, а иконка door завязана на Contact с показаниями open\close, то картинку door-open.png копируем в door-1.png, а door-close.png копируем в door-0.png.

Результат:


ps. Только я спросил про патч, сразу товарищи разработчики его наложили. Так что можете пробовать Contact item в ночном билде (я думаю это исправление войдет в версию 1.4, которая выйдет 9-го февраля 2014 года). Я пробовать не буду, так как меня пока устраивает на основе Numbers.

2 февраля 2014 г.

Owfs - установка из исходников

Начнем с лирического отступления. Проанализировав показания термометра DS18B20 я понял, что он немного завышает показания.   Погуглив я нашел две причины: либо самонагрев датчика от частого опроса, либо неоткаллиброванный датчик. Решил получше изучить логи owfs.

1. Включаем логи: /etc/owfs.conf

error_print = 1 
error_level = 3 

Перезапускаем owserver и смотрим что у нас в логах. (Обратите внимание, что я рассказываю про версию из deb пакета в init.d скрипте которого уже указан путь к конфигу). А в логах у нас пусто. Помните, как мы устанавливали систему? Позже мы поставили rsyslod.

Ищем # whereis owserver , чтобы запустить его не в режиме сервиса , а в консоли.

#/usr/bin/owserver --debug  --error_level=9 --error_print=2 --foreground -c /etc/owfs.conf --pid-file /var/run/owfs/owserver.pid
DEBUG MODE
libow version:
        2.8p15


И снова пусто. Но не только у нас. Похоже, что в deb пакете owfs логирование выключено.

Посему удаляем owfs (сохраним init.d скрипты и owfs.conf - хотя они удалиться не должны). Качаем версию посвежее. Распаковываем tar -xvzf... Устанавливаем необходимое для компиляции и сборки.

#apt-get install autoconf libtool libusb-dev libfuse-dev make ed
#cd /usr/src/owfs-2.9p1
#./configure --help
#/owfs-2.9p1# autoreconf -i

Я сконфигурировал следующим образом (также можно добавить опцию --enable-owtraffic Enable bus traffic reports (default false) - очень интересная опция, дающая возможность отслеживать трафик в самой 1-wire сети):

#./configure --enable-debian --disable-owftpd --disable-owperl --disable-owphp --disable-parport --disable-owpython
# make -j4
# make install

По умолчанию все устанавливается в директорию /opt/owfs/ . Сделаем линк в /usr/bin , что бы было проще использовать и не переписывать скрипты запуска.

# for p in owfs owserver owhttpd owftpd owread owwrite owdir ; do ln -sf /opt/owfs/bin/$p /usr/bin/$p ; done

Пробуем запускать:

/usr/bin/owserver --debug  --error_level 9 --error_print 2 --foreground -c /etc/owfs.conf --pid-file /var/run/owfs/owserver.pid

Если все хорошо, перезапускаем сервер с помощью init скрипта и смотрим syslog. Отлично! Теперь укажем всем клиентским приложениям использовать tcp сервер (owserver) для работы, ибо usb устройство уже занято им (то есть все приложения пакета owfs должны работать через owserver - если он запущен, либо по одиночке). Пропишем в конфиг (он должен автоматически подхватываться (ключ -c) всеми init.d скриптами пакета owfs, которые у нас остались после установки deb пакета из репозитория):

# With this setup, any client (but owserver) uses owserver on the
# local machine...
! server: server = localhost:4304

В конфиге программы с репозитория эта строчка уже указана.

Но скрипта для приложения (не пакет) owfs в init.d нет (вообще странный пакет в репозитории дебиана - логов нет, управление не понятно, такое ощущение, что делал человек, плохо знакомый с owfs). Можем сделать на основе скрипта owhttpd и запускаем:

# /etc/init.d/owfs start
[ ok ] Starting 1-Wire owfs Daemon: owfs.
root@debtruck:/etc/init.d# ps -A | grep ow
 2478 ?        00:00:01 owserver
 3262 ?        00:00:00 owfs

Смотрим работающие логи.