Показания с термометра — через веб-интерфейс на роутере

в 12:07, , рубрики: 1-wire, diy или сделай сам, Песочница, роутер, метки: , ,

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

При работе над своим дипломом мне в руки попал датчик DS18B20.

Показания с термометра — через веб интерфейс на роутере

Это термометр с цифровым выходом, передающий данные по протоколу 1-wire. После некоторых размышлений было решено научить мой многострадальный роутер отображать внешнюю температуру, для статистики и просто из любопытства. У меня стоит Linksys Е3000 с альтернативной прошивкой  DD-WRT v24-sp2 (04/13/11) big. Обычная прошивка для таких дел не годится, она не дает доступа к необходимым в дальнейшем функциям роутера. Мое личное мнение — DD-WRT самая лучшая и самая богатая функциями альтернативная прошивка. Ну как можно не влюбиться в прошивку, которая поддерживает BGP на домашнем роутере с 64 МБ оперативной памяти) Ниже показан веб-интерфейс прошивки DD-WRT.

Показания с термометра — через веб интерфейс на роутере

Обычно для передачи данных по 1-wire используют COM или LPT порт, но, к сожалению, на данном роутере есть только один разъем USB. Точнее, у него есть разводка под UART на самой плате, но тогда придется мириться с отсутствующей крышкой на роутере, что на корню губит дизайнерский талант фирмы Linksys. В таком случае для работы с датчиком можно использовать преобразователи USB – RS-232 вроде pl2303. Но для корректной работы этого преобразователя нужны драйвера. Сразу скажу, что не стоит поступать как я и компилировать их из исходников, потому что драйвера для pl2303 уже включены в прошивку DD-WRT и просто не загружены) Чтобы загрузить их придется подключится по протоколам ssh или telnet к роутеру пройти авторизацию (имя пользователя — root, пароль — тот же, который вы задали в веб-интерфейсе) Если все прошло удачно, то вы видите примерно такую картинку:

Показания с термометра — через веб интерфейс на роутере

Как вы уже поняли, это unix система (не IOS, к сожалению, Linksys не Cisco), поэтому трудностей с адаптацией к оболочке возникнуть не должно должно.

Находятся драйвера в директории /lib/modules/2.6.24.111/kernel/drivers/usb/serial и называються usbserial.ko и pl2303.ko. 2.6.24.111 это версия ядра и потом она вполне может измениться в будущем) Загружаются они командами insmod usbserial.ko и insmod pl2303.ko из каталога, где они содержатся. Если переходник USB – RS-232 подключен, то после этих команд должно появится устройство по адресу /dev/usb/tts/<№ устройства>, в моем случае номер 0. Проконтролировать загрузку драйверов можно через dmesg, он должен показать что-то подобное:

registered new interface driver usbserial
drivers/usb/serial/usb-serial.c: USB Serial Driver core
drivers/usb/serial/usb-serial.c: USB Serial support registered for pl2303
pl2303 1-1.3:1.0: pl2303 converter detected
usb 1-1.3: pl2303 converter now attached to ttyUSB0
usbcore: registered new interface driver pl2303
drivers/usb/serial/pl2303.c: Prolific PL2303 USB to serial adaptor driver

Следующее, что надо сделать, это добавить программу, которая умеет работать с 1-wire.

Называется она digitemp и распостраняется под GNU General Public License. Вы можете скомпилировать его под ваш роутер или поискать в интернете скомпилированную программу под вашу прошивку. Но здесь есть небольшой подводный камень – непосредственно в ПЗУ программу записать не удастся вследствии аппартных особенностей маршрутизатора. Записать можно или в /tmp, иначе говоря – в оперативную память, где будет благополучно стерто после перезагрузки, или на флешку, которая будет подключена через usb хаб. Крайне желательно чтобы хаб был активным, иначе при загрузке роутера может не хватить питания одновременно на флешку и pl2303 и одно/оба устройства опознаются в системе некорректно.

Для работы флешки необходимо чтобы в веб-интерфейсе роутера были выбраны пункты Core USB Support, Automatic Drive Mount и была указана точка монтирования в Disk Mount Point. Все это находится в веб-интерфейсе в разделе Services > USB. У меня флешка монтировалась в /opt.

Следующее что нужно проверить — как работает digitemp. Проверяется это командами ./digitemp -s /dev/usb/tts/0 –i (инициализация устройства) и ./digitemp -a (считывание температуры со всех датчиков, которых пока одна штука). Как написано в руководстве, инициализировать надо один раз, но при считовании данных по расписанию оказалось необходимо каждый раз инициализировать заново. Если все прошло удачно, то вывод команд должен быть примерно такой:

DigiTemp v3.3.2 Copyright 1996-2004 by Brian C. Lane
GNU Public License v2.0 — http:#www.brianlane.com
Turning off all DS2409 Couplers
.
Searching the 1-Wire LAN
28B6ACDA020000EC: DS18B20 Temperature Sensor
ROM #0: 28B6ACDA020000EC
Wrote .digitemprc
Nov 01 16:40:13 Sensor 0 C: 20.88 F: 69.57

Вся аппаратная часть в сборе:

Показания с термометра — через веб интерфейс на роутере

Дело осталось за малым — созданием веб-интерфейса для отображения температуры.

Вариантов для его создания было достаточно много, но я остановился на создании динамической веб-страницы на основе cgi-bin. Данные она получает из тектовых файлов, которые по сути просто результат запуска digitemp по крону. Для корректной работы крона требуется настроить NTP клиент на роутере, для того, чтобы время при снятии данных было точным. Делается это в разделе Setup –> Basic Setup – Time Settings веб-интерефейса DD-WRT. Там необходимо сначала запустить его (выбрать пункт enable), потом задать Time zone (временную зону), Summer Time (DST) (переход на летнее время), и задать в настройке Server IP/Name имя или адрес NTP сервера, скажем, один из адресов ВНИИФТРИ (ntp1.vniiftri.ru). После сохранения изменений и перезагрузки роутер сихронизирует время с Государственным эталоном времени и частоты.

К сожалению, из-за уязвимости в DD-WRT у последних версий отключена обработка cgi-bin скриптов из пользовательской директории, поэтому для динамической странички необходимо устанавливать отдельный веб-сервер, которым я выбрал lighttpd. Сама страничка написана на perl, в качестве обработчика выбран microperl, соответственно в конфигурации lighttpd раскомментирован mod_cgi, он y необходим для работы веб-страницы. Ниже приведены изменения в стандартную конфигурацию lighttpd.

server.document-root = "/opt/share/www/"
#Директория, в которой будут находится файлы веб-страниц.
index-file.names = ( «index.cgi»)
#Страница по умолчанию.
server.event-handler = «poll»
#Тип обработки событий.
server.tag = «lighttpd»
#подпись веб-сервера, будем вежливыми
static-file.exclude-extensions = ( ".fcgi", ".php", ".pl", ".py", ".rb", ".cgi")
#Запрет на обработку следующих страниц как статических.
server.port = 8081
#Порт, на котором будет работать веб-сервер.
server.username = «nobody»
#Имя пользователя, под которым будет работать веб-сервер.
server.groupname = «65534»
#Группа пользователя, под которым будет работать веб-сервер.
cgi.assign = ( ".pl" => "/opt/bin/ microperl",
".cgi" => "/opt/bin/microperl" )
#задает, какой обработчик использовать для веб-страниц на основе cgi-bin.

Для отображения графика температуры используется библиотекa Raphael. Сами листинги приводить не буду, из-за их большого объема и малой информативности.

И последний штрих — чтобы все работало и после перезагрузки, была добавлена правка в конфигурацию startup скрипта в веб-интерфейсе DD-WRT.

insmod /lib/modules/2.6.24.111/kernel/drivers/usb/serial/usbserial.ko
insmod /lib/modules/2.6.24.111/kernel/drivers/usb/serial/pl2303.ko
//загрузка драйверов для работы термометра
chmod 666 /dev/usb/tts/0
chmod 666 /opt/var/log/lighttpd/error.log
chmod 666 /opt/var/log/lighttpd/access.log
//Изменение прав доступа к файлам, хотя с такими числами только демонов запускать.
grep -q nobody /etc/passwd || echo «nobody:*:65534:65534:nobody:/var:/bin/false» >> /etc/passwd
//Создание пользователя, под которым будет работать lighttpd (Небольшая паранойя еще никому не навредила!)
lighttpd -f /opt/etc/lighttpd/lighttpd.conf
// Запуск самого lighttpd в режиме демона (операционная система такая, а не я...).

Еще добавлена одна строчка в cron, она и отвечает за снятие данных по расписанию.
0 * * * * root sh /opt/input.sh

Содержимое скрипта input.sh (Который и считывает каждый час данные с датчика)

#!/bin/
/opt/share/./digitemp -s /dev/usb/tts/0 -i;
/opt/share/./digitemp -a -o %.2C | tail -n 1 >> /opt/share/www/temp1.txt
#Пишет в файл temp1.txt температуру с датчика, в градусах Цельсия, два знака после запятой.
tail -n 24 /opt/share/www/temp1.txt > /opt/share/www/temp.txt
#Вырезает последние 24 значения температуры из файла.
date +%R >> /opt/share/www/time1.txt
#Записывает час, в который сняты данные.
tail -n 24 /opt/share/www/time1.txt > /opt/share/www/time.txt
#Вырезает последние 24 значения температуры из файла.

Таким образом мы получаем температуру за последние сутки.
После всей настройки при обращении на страницу 192.168.1.1:8081 будет показываться это:

Показания с термометра — через веб интерфейс на роутере

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

Автор: chaynick

* - обязательные к заполнению поля