Пользователь
0,0
рейтинг
5 октября 2012 в 12:27

Включение чего угодно по HTTP без заморочек c OpenWRT из песочницы tutorial


В комментариях к статье об опыте изготовления «интернет розетки» мое внимание привлекли два комментария. Один, в котором утверждалось, что такая штука, по сути, бесполезна, показался мне несправедливым — хорошо помню, как мне однажды понадобилось, например, дистанционно «ресетить» одну хитрую штучку и думаю, что я не одинок. А вот идея о том, что можно решить подобный вопрос проще и дешевле, использовав, например, TP-LINK TL-MR3020 + OpenWRT показалась мне дельной. Я решил к тому же обойтись без разборки устройства, программирования и микроконтроллеров — короче, сделать решение как можно доступнее. И у меня это почти получилось!

В качестве устройства вывода используем обычную клавиатуру USB. Встречая в супермаркетах клавиатуры отвратительного качества по смешным ценам, я всегда удивлялся — для чего же она может понадобиться? Да вот же для чего! В клавиатуре три светодиода, которыми можно программно управлять с любого устройства, эту клавиатуру поддерживающего. Заменив светодиоды цепью управления — получаем управление тремя нагрузками. В качестве бонуса – возможность дальнейшей доводки устройства для использования как устройства ввода. Конечно, можно не стрелять из пушки по воробьям, собрать (или приобрести) простейшее устройство на микроконтроллере, у которого будут неосопоримые преимущества (большее количество входов/выходов, нормальные логические уровни и т.п.). Но у «клавиатурного» подхода тоже есть плюсы — он доступен людям, незнакомым с МК, не имеющим программатора. Можно просто взять и сделать работающее устройство сегодня, сейчас. Кроме этого, среди плюсов:
  • решение легко переносимо на другие платформы: я не проверял, но в теории это можно воткнуть в любой «ASUS» или «D-Link», мирно раздающий инет из своего угла (если у него есть USB) — и будет работать;
  • роутер при этом можно использовать по прямому назначению;
  • не требуется разборки роутера и вмешательства в его схему (а TL-MR3020, кстати, нелегко разобрать);
  • не тебуется программирования (если не считать программой небольшой шелл-скрипт) и компиляции;
  • все компоненты можно приобрести в компьютерном магазине (это если просто «помигать светодиодом», для реального управления придется купить пару доступных радиокомпонентов), при этом общие затраты составят менее 1500 рублей.

Ставим OpenWRT и настраиваем сетевой интерфейс

Для этого шага понадобится, собственно, роутер. Мой мне обошелся в 850р.
Страница модели на openwrt.org дает исчерпывающие инструкции по перепрошивке и разрешает нам пользоваться снэпшотом транка. Сам же робко предложу взять бету Attitude Adjustment 12.09. Тем более, что на момент публикации снэпшоты недоступны на сайте openwrt, а A.A.12.09 наконец-то выложили.
Установка состоит из нескольких элементарных операций:
  1. Настройте сетевое подключение вашего ПК на автоматическое получение IP-адреса и подключите роутер Ethernet-кабелем (после перепрошивки WiFi-интерфейс будет отключен)
  2. Войдите на страницу администрирования роутера (адрес по умолчанию 192.168.0.254 пользователь:admin, пароль:admin )
  3. На вкладке System Tools > Firmware upgrade выберите скачаную ранее прошивку, нажмите «Upgrade» и дождитесь, пока индикатор загрузки дважды дойдет до 100%.
  4. Так как сетевые параметры OpenWRT по умолчанию отличаются от TP-LINK'овских — самый простой способ переинициализировать интерфейс — отсоединить и снова подсоединить ethernet-кабель.
  5. Заходим на роутер по telnet (192.168.1.1 — адрес «свежей» OpenWRT по умолчанию) и задаем пароль командой passwd — теперь роутер доступен по SSH (и недоступен по telnet).


Для установки дополнительных пакетов нужен доступ к репозиторию через интернет, что требует его конфигурации как клиента локальной сети.
Например:
Для настройки статического IP в сегменте 192.168.1.x сделаем следующее:
uci set network.lan.proto=static
uci set network.lan.ipaddr=192.168.1.222
uci set network.lan.netmask=255.255.255.0
uci set network.lan.gateway=192.168.1.1
uci set network.lan.dns=8.8.8.8
uci changes
uci commit
/etc/init.d/network restart

Где 192.168.1.1 — адрес шлюза в нашей сети, а 192.168.1.222 — незанятый IP, который и будет присвоен нашей коробочке. Команда «uci changes» предоставляет возможность просмотреть все внесенные изменения. Я стараюсь не пренебрегать этой возможностью, так как устройство с неправильно настроенным интерфейсом, будучи недоступным извне, превращается в «зомби». На случай, если все таки неприятность произошла, в OpenWRT предусмотрен «режим восстановления»: при загрузке, как только кнопка «WPS» начнет мигать, зажмите ее — MR3020 загрузится с сетевыми параметрами по умолчанию.
Если в сети работает DHCP, можно задать автоматическую конфигурацию:
uci set network.lan.proto=dhcp
uci set network.lan.hostname=etherelay
uci commit
/etc/init.d/network restart

Вторая строчка необязательна, но может быть крайне полезна для поиска устройства. Можно будет обращаться к устройству не по IP, а по hostname, если сеть это поддерживает. Если хотите на 100% избежать поиска устройства в сети — применяйте статическую конфигурацию.
Полезно также запретить работу встроенного в наш TP-LINK dhcp-сервера:
uci set dhcp.lan.ignore=1
uci commit
/etc/init.d/dnsmasq restart

Все, можно отключать нашу коробочку от компьютера (все равно ssh-сессия уже оборвалась после последней команды) и подключать ее к роутеру или свитчу.

Подключение клавиатуры и проверка управления светодиодами

Сайт H-WRT информирует нас, что для установки клавиатуры нужен лишь модуль kmod-usb-hid.
Установим его:
opkg update
opkg install kmod-usb-hid

Самое время подключить клавиатуру и посмотреть, опозналась ли она:
root@OpenWrt:~# dmesg | tail
[   66.380000] hub 1-0:1.0: connect-debounce failed, port 1 disabled
[   68.780000] hub 1-0:1.0: connect-debounce failed, port 1 disabled
[   71.180000] hub 1-0:1.0: connect-debounce failed, port 1 disabled
root@OpenWrt:~# 

Облом! это совсем не то, что я ожидал. В чем же дело?
Схожий багрепорт быстро находится — разработчики объясняют такое поведение аппаратными ограничениями примененного чипсета. Похоже, находящийся «на борту» USB-хаб не жалует low-speed устройства. Хотя на этом моменте дух Дзен бесследно испарился — не будем опускать руки и попробуем решить проблему подключением клавиатуры через внешний USB-хаб:
root@OpenWrt:~# dmesg | tail
[  143.120000] usb 1-1: new high-speed USB device number 2 using ehci-platform
[  143.270000] hub 1-1:1.0: USB hub found
[  143.270000] hub 1-1:1.0: 4 ports detected
[  143.580000] usb 1-1.2: new low-speed USB device number 3 using ehci-platform
[  143.730000] input: Generic USB Keyboard as /devices/platform/ehci-platform/usb1/1-1/1-1.2/1-1.2:1.0/input/input0
[  143.730000] generic-usb 0003:040B:2000.0001: input: USB HID v1.10 Keyboard [Generic USB Keyboard] on usb-ehci-platform-1.2/input0
[  143.770000] input: Generic USB Keyboard as /devices/platform/ehci-platform/usb1/1-1/1-1.2/1-1.2:1.1/input/input1
[  143.780000] generic-usb 0003:040B:2000.0002: input: USB HID v1.10 Mouse [Generic USB Keyboard] on usb-ehci-platform-1.2/input1
root@OpenWrt

Гораздо лучше. Пускай из-за этого пришлось написать «почти получилось» в начале статьи и «способ сервировки» на фото, но так наша «Generic USB Keyboard» опозналась. На клавиатуру всегда создается два «устройства», но даже и не спрашивайте, почему эта конкретная клавиатура назвалась еще и мышью… Так или иначе — мы готовы к «аппаратному хеллоуворлду» — включить светодиод.
cat /dev/input/event0 > /dev/null &
printf "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x01\x00\x00\x00\x01" > /dev/input/event0

Здесь должен торжественно зажечься светодиод «Caps Lock». Те, кого просто радует этот факт — могут переходить к следующему шагу. Те, кто не может двинуться дальше, не узнав, что за бредовое заклинание приведено выше — заглядывают в
сумбурные пояснения:
На все, что происходит с клавиатурой (или другим устройством ввода) генерируется событие ввода, видимое в соответствующем ему файле (в нашем случае /dev/input/event0, но это частный случай, обусловленный тем, что других устройств ввода не подключено). Структура события определяется в заголовочном файле input.h:
 struct input_event {
         struct timeval time;
         __u16 type;
         __u16 code;
         __s32 value;
 };

Где type сигнализирует о типе элемента ввода (кнопка клавиатуры или перемещение мыши/джойстика и т.п ), code — код элемента, специфичный для каждого типа (например, для клавиатурного события EV_KEY здесь будет передан номер клавиши), а value — это, соответственно, какое воздействие и какой величины (для устройств, поддерживающих это) было произведено. Например, при нажатии клавиши «Q» на клавиатуре мы получим:
root@OpenWrt:~# cat /dev/input/event0 | hexdump 
0000000 505b 0ed9 0009 6bdd 0004 0004 0007 0014
0000010 505b 0ed9 0009 6be6 0001 0010 0000 0001
0000020 505b 0ed9 0009 6bec 0000 0000 0000 0000
0000030 505b 0ed9 000a 2756 0004 0004 0007 0014
0000040 505b 0ed9 000a 275e 0001 0010 0000 0000
0000050 505b 0ed9 000a 2762 0000 0000 0000 0000

где первые 8 байт (505b 0ed9 000* ****) — время события, следующие два байта (0001) — тип события (EV_KEY), затем два байта номера клавиши (0010), которые для алфавитно-цифровых клавиш соответствуют скан -коду в Set 1. Кстати, нажатия всяких «прокачанных» клавиш вроде регулировки громкости, управления воспроизведением и т.п. отправляются во второй обработчик, созданный для клавиатуры (в нашем случае /dev/input/event1). Для них не генерируется событие автоповтора, что может оказаться весьма кстати — помните, я писал о «бонусной» возможности устройства работать на ввод? Последние 4 байта (0000 0001 или 0000 0000) указывают на то, что произошло нажатие или отпускание соответственно. Пакеты, состоящие из нулей — это специальные разделительные события EV_SYN, а зачем нужны события с типом 4 я не знаю. Определения для типов и кодов заданы в том же input.h, и подробнее описаны в этом документе. Дальше начинается самое интересное. Хотя большая часть событий передается от устройства в пространство пользователя, некоторые события могут идти в обратном направлении. Это сделано для поддержки, например, джойстиков с отдачей или (та-дам!) светодиодов. То есть, записав в /dev/event/input0 событие с типом EV_LED, кодом LED_CAPSL и значением 1, мы скомандуем клавиатуре зажечь светодиод «Caps Lock». Достаточно подробно о работе с устройствами ввода, особенно USB, рассказывают статьи Брэда Хардса (Brad Hards) The Linux USB Input Subsystem и Using the Input Subsystem (продолжение первой статьи, даже с примером кода для управления светодиодом). Жаль что я их нашел слишком поздно, когда задача уже была решена экспериментальным путем. Между прочим, мне очень повезло — последние снэпшоты, а так же бета 12.09 имеют одну особенность, из за чего отсылка событий работает нестабильно, если файл устройства постоянно не читать. Именно для этого предназначена команда
cat /dev/input/event0 > /dev/null &
Я экспериментировал сначала с прошивкой r31214, где таких особенностей не было, поэтому светодиод у меня загорелся сразу — если бы этого не произошло, то я бы еще долго искал верный путь.

Скрипт

Чтобы автоматизировать управление светодиодами нам нужен скрипт. Для того, чтобы на следующем шаге мигать ими по HTTP — сразу положим его в папку /www/cgi-bin:
cd /www
mkdir cgi-bin
cd cgi-bin
wget http://etherelay.googlecode.com/files/ctlrelay
chmod +x ctlrelay

Вот его текст и описание:
#!/bin/sh

KB_LEDS=/dev/input/event0
EV_LED="\x00\x11"
LED_NUML="\x00\x00"
LED_CAPSL="\x00\x01"
LED_SCROLLL="\x00\x02"
TURN_ON="\x00\x00\x00\x01"
TURN_OFF="\x00\x00\x00\x00"
DT_DUMMY="\x00\x00\x00\x00\x00\x00\x00\x00"

#формируем 16-байтовые посылки для отсылки в файл клавиатуры
NUM_ON=$DT_DUMMY$EV_LED$LED_NUML$TURN_ON
NUM_OFF=$DT_DUMMY$EV_LED$LED_NUML$TURN_OFF
CAPS_ON=$DT_DUMMY$EV_LED$LED_CAPSL$TURN_ON
CAPS_OFF=$DT_DUMMY$EV_LED$LED_CAPSL$TURN_OFF
SCROLL_ON=$DT_DUMMY$EV_LED$LED_SCROLLL$TURN_ON
SCROLL_OFF=$DT_DUMMY$EV_LED$LED_SCROLLL$TURN_OFF

#"костыль", обеспечивающий чтение файла клавиатуры на время записи
if ! ps | grep -qe "[c]at $KB_LEDS"; then  cat $KB_LEDS > /dev/null & fi

#берем команду  из "переменной" command GET-запроса
#если эапроса нет - берем команду из первого аргумента
if [ -z "$QUERY_STRING" ]; then COMMAND=$1;
else
COMMAND=`echo "$QUERY_STRING" | sed -n 's/^.*command=\([^&]*\).*$/\1/p'`
printf "Content-type: text/plain\r\n\r\n"
fi

#посылка события в файл обработчика
case $COMMAND in
        num_on)
                printf $NUM_ON  > $KB_LEDS;;
        num_off)
                printf $NUM_OFF > $KB_LEDS;;
        caps_on)
        	printf caps_on > /var/rrr
                printf $CAPS_ON > $KB_LEDS;;
                
        caps_off)
        	printf caps_off > /var/rrr
                printf $CAPS_OFF > $KB_LEDS;;
        scroll_on)
                printf $SCROLL_ON > $KB_LEDS;;
        scroll_off)
                printf $SCROLL_OFF > $KB_LEDS;;
        num_pulse)
                printf $NUM_ON  > $KB_LEDS
                sleep 1
                printf $NUM_OFF > $KB_LEDS
                ;;
        caps_pulse)
                printf $CAPS_ON > $KB_LEDS
                sleep 1
                printf $CAPS_OFF > $KB_LEDS
                ;;
        scroll_pulse)
                printf $SCROLL_ON > $KB_LEDS
                sleep 1
                printf $SCROLL_OFF > $KB_LEDS
                ;;
        *)      WRONG_ARG=1;;
esac

#обновляем информацию в файле текущего состояния светодиодов
if [ -z $WRONG_ARG ]
then
        STATE_FILE=/var/ledstate
        DEFAULT_STATE={\"num\":false,\"caps\":false,\"scroll\":false}
        if ! [ -e $STATE_FILE ]; then  echo $DEFAULT_STATE > $STATE_FILE; fi
        AFFECTED_LED=`echo $COMMAND | sed -r -e 's/_[a-z]+$//'`
        NEW_STATE=`echo $COMMAND | sed -r -e 's/^[a-z]+_//' -e 's/on/true/' -e 's/off|pulse/false/'`
        sed -i -r 's/"'"$AFFECTED_LED"'":[a-z]+/"'"$AFFECTED_LED"'":'"$NEW_STATE"'/' $STATE_FILE
fi

Константы EV_LED, LED_NUML, LED_CAPSL, LED_SCROLLL, как я уже говорил, определены в input.h. Время нас не волнует — забиваем его нулями. Конечно, код получится компактнее, если формировать «события» «на лету», исходя из полученной команды, а не просто отсылать заранее набитые шаблоны в свитче, но мне показалось, что так понятнее основная идея. Нам все так же необходимо чтение из файла событий во время записи в него, откуда и возник пресловутый костыль. Повторюсь, в этом не было необходимости в более ранних сборках, и, скорее всего, не понадобится в будущем. Но пока придется мириться. Последний фрагмент модифицирует файл текущего состояния светодиодов, который состоит из одной примерно такой строчки:
{"num":true,"caps":false,"scroll":false}
Если такого файла нет — он будет создан со всеми значениями «false». В OpenWRT директория /var/ — в оперативке, а значит — файл создается после каждой перезагрузки, когда все светодиоды как раз выключены. Уютненькая схемка! Как вытащить параметры из HTTP — запроса я прочитал, наверное здесь (прочитал давно и ссылку не сохранил, только строчку кода, но здесь очень похоже). Скрипт выводит «Content-type: text/plain», если вызван через CGI, потому что иначе результат запроса будет 502 (Bad Gateway), а не 200(OK), что не смертельно, но некрасиво.

Теперь управлять светодиодами легко. Чтобы включить, скажем, светодиод «Scroll Lock», пишем:
./ctlrelay scroll_on

Выключаем:
./ctlrelay scroll_off

Можно еще «мигнуть» (scroll_pulse). Как говорит уже многими здесь уважаемый Anant Agarwal: «I could do this all day. This is so much fun!». Но все же, перейдем к следующему этапу и создадим…

Веб-интерфейс

Какой же веб-интерфейс без веб-сервера? Проверим его наличие:
opkg status uhttpd

Если в выводе есть строка Status: install user installed (а это будет так, если вы используете Attitude Adjustment 12.09 beta) то сервер уже установлен. Иначе установим его и настроим его запуск:
opkg update
opkg install uhttpd
/etc/init.d/uhttpd enable
/etc/init.d/uhttpd start

Дальше нам нужна веб-страница:
<!DOCTYPE html>
<html>
<head>
    <title>Relay control</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <script type="text/javascript">
        function command(action)
        {
            url="/cgi-bin/ctlrelay?command="+action;
            url=url+"&fuie=" + Math.random(); 
            var xmlhttp=new XMLHttpRequest(); 
            xmlhttp.open("GET",url,false);
            xmlhttp.send();
        }
        function get_status()
        {
            var xmlhttp=new XMLHttpRequest();
            xmlhttp.onreadystatechange=function()
            {
                if (xmlhttp.readyState==4 && xmlhttp.status==200)
                {
                    ledstate = JSON.parse(xmlhttp.responseText)
                    for (led in ledstate)
                    {
                        document.getElementById(led).checked=ledstate[led]
                    }
                }
            } 
            xmlhttp.open("GET","/ledstate?fuie="+ Math.random(),false);
            xmlhttp.send();
            setTimeout("get_status()",500);
        }
    </script>
</head>

<body onload="get_status()">
<div class="controls">
<div class="control">
<label for="scroll">Scroll Lock LED</label>
<input id="scroll" type="checkbox" onclick="if (this.checked) command ('scroll_on'); else command ('scroll_off')">
</div>
<div class="control">
<label for="caps">Caps Lock LED</label>
<input id="caps" type="checkbox" onclick="if (this.checked) command ('caps_on'); else command ('caps_off')">
</div>
<div class="control">
<label for="num">Num Lock LED</label>
<button id="num" type="button" onclick="command('num_pulse')">1s blink</button>
</div>
</div>
</body>
</html>

Сначала я хотел использовать JQuery.get(), но потом посчитал излишним привлекать JQuery ради всего лишь пары GET-запросов. У нас есть две JavaScript функции. Первая, command(action), запускает наш скрипт, передавая «команду» в праметре «command» GET-запроса. Какую именно — определяется в событиях onclick элементов управления. Это выглядит не очень элегантно, спору нет, но дает хорошее представление о том, как все работает. Вторая функция, get_status() запускается по событию onload, запрашивает файл с текущим состоянием светодиодов (тот, который формируется в конце скрипта) и отражает его на элементах управления страницы. По невероятному стечению обстоятельств файл состояния представляет из себя JSON-представление ассоциативного массива, и доступ к данным мы очень просто получаем с помощью JSON.parse(). Повтор запроса каждые полсекунды позволяет отслеживать измения состояния, произведенные с другого клиента. Добавка в url fuie=Math.random() нужна для того, чтобы адрес каждый раз был уникальным — тогда браузер не сможет отказаться от запроса страницы, посчитав, что она уже есть в кэше. Как можно догадаться из названия переменной, особенно склонен к такому поведению Internet Explorer.

Маленький нюанс — браузер, конечно, не имеет доступа к папке /var на сервере, поэтому предоставим ему возможность прочитать файл ledstate оттуда, куда он «дотягивается», с помощью симлинка:
ln -s /var/ledstate /www/ledstate

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

Схема

Уже можно разобрать клавиатуру и вытащить из нее плату:

Схему включения светодиодов клавиатуры представим следующей (весьма упрощенной) моделью (для включенного состояния):
схема включения светодиодов клавиатуры
Схема 1. Включение светодиода клавиатуры
Три проверенных «клавы» из «помоечного» сегмента имели именно такое включение светодиодов, отличаются только их токи — обычно около 18мА, но бывает и 3мА. Надо иметь ввиду, что возможны и другие схемы.
Самое простое — если необходимо коммутировать небольшое напряжение и ток (дистанционный «Reset» какого — либо устройства или эмуляция других кнопок/логических сигналов). Можно обойтись обычной оптопарой:
схема подключения оптопары к клавиатуре для управления логическими уровнями
Схема 2. Формирование логического сигнала
Для управления устройством с питанием от сети берем твердотельное реле:
схема включения твердотельного реле вместо светодиода клавиатуры
Схема 3. Управление твердотельным реле
Я использовал отечественнное реле К293КП13П из-за цены в 170 рублей. Максимальный ток в нагрузке, на которое оно рассчитано — 1А. Ток через управляющий светодиод не должен быть ниже минимального (в документации он обозначается IFmin) для используемого типа реле. Если плата клавиатуры дает меньший ток (отпаяйте один вывод светодиода и измерьте ток в разрыве) — поможет дополнительный транзисторный ключ:
включение твердотельного реле через транзисторный ключ.
Схема 4. Подключение твердотельного реле через ключ
Он же спасет, если используется твердотельное реле, управляемое напряжением или «классическое» электромеханическое реле:
схема подключения реле вместо светодиода клавиатуры
Схема 5. Управление электромеханическим реле
Твердотельное реле — штука достаточно дорогая, и чем мощнее — тем дороже. Обычное реле дает больше «ампер на рубль», но имеет свои минусы. Среди них — большой потребляемый ток во включенном состоянии. Если одновременно включить три реле такой же модели, как на схеме — потребляемый от USB ток будет составлять почти 300 мА. Если не хотите так сильно «доить» порт — подключайте эмиттер не к нему (пунктирная линия на схеме), а к независимому источнику.
Схемы 4 и 5, само собой, работают только на клавиатурах где СД включены именно по схеме с «общим анодом» (проверьте сопротивление между анодами диодов и «плюсом» платы — должно быть 0 Ом). Если неохота с этим заморачиваться — можно использовать вместо ключа маломощное оптореле. Включается вместо штатного светодиода и работает при токе на светодиод от 5 до 25 мА, то есть подойдет для всех вариантов клавиатур с вероятностью 99%. Если вам надо коммутировать напряжение до 60 в и ток до 300 мА — можно убрать реле и пользоваться оптореле напрямую.
схема подключения реле вместо светодиода клавиатуры
Схема 6. Управление электромеханическим реле при помощи оптореле
В схеме и ее реализации много упрощений:
Неплохо добавить в коммутируемую цепь предохранитель. Транзистор в схеме 5 работает с почти максимальным коллекторным током — желательно взять с током срабатывания поменьше, или хотя бы транзистор помощнее. На выходы твердотельного реле нужно поставить демпфирующую RC-цепочку при работе на двигатель или другую индуктивную нагрузку. Компоненты подбирались лишь по критерию доступности и цены в ближайшем (ко мне) оЧень Дорогом радиомагазине — при наличии выбора можно подобрать у нормального продавца «твердотелку» на нужный ток с широким диапазоном IF и на том закрыть вопрос с коммутацией. Кроме того, представленная модель включения неточна: плата клавиатуры ведет себя как источник тока по отношению к нашему «светодиоду» только при напряжении на аноде 2.5В и выше — я старался, по возможности, обеспечить падение напряжения, сходное с таковым у заменяемого светодиода, чтобы плата «не почувствовала» подмены.
Что всегда стоит принимать в расчет — это элементарая электробезопасность. Даже тестовое устройство — особенно тестовое устройство, которое наверняка будет болтаться где-нибудь на проводках или будет забыто включенным среди прочего хлама на столе — надо защитить от случайного касания токоведущих частей, если оно предусматривает подключение к сети. Иначе по вам может потечь абсолютно реальный электрический ток.
Я собрал варианты 3 и 6 на макетке, получилось так:

Несмотря на то, что это не более чем «proof of concept», мне захотелось хоть немного «навести красоту», пускай и в собственной извращенной трактовке. Такие уж нынче времена: внешний вид ценится не меньше, а порой и беспричинно больше функциональной нагрузки. Что и приводит нас к следующему этапу.

Косметика и демонстрация

От HTML — интерфейса за километр несет ботанщиной, байковыми рубашками с катышками и макаронами из стеклянной банки:

Попытаемся это хоть как-то скрасить.
  1. Так как художественные способности у меня на нуле, а вкус где то рядом с ними — идею я стырил отсюда я почерпнул вдохновение (и немного css) здесь: http://www.seanslinsky.com/demo/ios-toggle-switches/.
  2. С помощью генератора градиентов mudcu.be/bg сделал нескучные обои задник.
  3. Генератор «клевых тумблерков» proto.io/freebies/onoff создает кнопки, которые работают почти во всех браузерах — даже в Опере, если сделать их квадратными, и даже в IE, если он >=9.
  4. Так как на разных системах по разному работает увеличение — делаем кнопки масштаба внутри страницы davidwalsh.name/change-text-size-onclick-with-javascript

CSS не имеет смысла приводить, потому что на 90% сгенерирован автоматически, а HTML — на 90% повтор вышеприведенного. Поэтому просто пишу как из скачать:
cd /www
mkdir luci
mv index.html luci
wget http://etherelay.googlecode.com/files/index.html
wget http://etherelay.googlecode.com/files/style.css

Вторая и третья строчка «перепрятывают» файл веб-интерфейса роутера (если он установлен) в отдельную папку, теперь он доступен по адресу _адрес_роутера_/luci. А «главной» страничкой, доступной по адресу сервера, становится наша.
Ну и, напоследок — говорят, что картинка стоит тысячи слов. В этом видео почти тысяча картинок. Надеюсь, оно хоть как-то уравновесит мою многословность.
Update: nm11 подсказал, как добавить авторизацию на веб-сервер (например, с логином wizard и паролем lumos ):
uci set uhttpd.main.config=/etc/httpd.conf
uci commit uhttpd
echo "/:wizard:lumos" > $(uci get uhttpd.main.config)
/etc/init.d/uhttpd restart
Павел Громовиков @pja
карма
25,5
рейтинг 0,0
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

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

Комментарии (61)

  • +2
    вместо TP-LINK можно поставить Raspberry Pi, у него и ноги есть сразу
    • +4
      Согласен, но Pi ко мне все еще не пришла (попросили недавно обождать еще недель восемь), а TP-Link я за углом купил. И у Pi нет WiFi на борту.
      • +2
        а ещё tp-link дешевле, ну и из него можно вывести уарт например в ардуинку, just for credits
    • +2
      Вы бы ещё Ардуино с Ethernet-шилдом предложили…
      • 0
        PIC18F67J60
    • 0
      Эм, какие ноги? У него же GPIO только вроде?
      • 0
        А GPIO, по-вашему, что такое? General Purpose Input/Output — как раз те самые «ноги».
  • +3
    Автор, скажите, а ваш прибор позволяет вернуть такси?
    • +1
      Само собой. Видите, на видео телефон — надо взять его, позвонить и попросить вернуть такси.
  • +1
    Можно и 7мью нагрузками рулить, добавив небольшую логическую развязку)
    • +1
      Только 4. Так как практически невозможно выставить нужное состояние на всех «светодиодах» одновременно. Соответственно, один сигнал уйдет на стробирование, и у нас останется два жалких бита (. Тут я хотел решить все так просто, как только возможно. А если нужно больше выходов — лучше присобачить МК с поддержкой USB — и получить все, что нужно. Вот недавно было интересное решение: habrahabr.ru/post/152401/. Tiny даже в ненавистном красном магазине стоит 4 доллара — и управляй хоть десятью нагрузками!
      • 0
        А вы не думали подцепить serial-converter и задействовать какой-нибудь копеечный чип на обработку сигналов с RS232? Там же при таком раскладе получаются почти безграничные возможности, в т.ч. обратная связь и прочее :)
        • +2
          Это уже было. Собственно, я от этой статьи и отталкивался. Мне показалось конвертер + контроллер = слишком много всего. А тут — одна платка и все. Но — не срослось — пришлось использовать еще и хаб, очень жаль. В любом случае, для расширения возможностей я считаю serial лишним звеном. Сильно дешевле не будет — тот же Prolific или FTDI тоже стоят денег. Тогда уж надо МК цеплять прямо к USB, как я собственно выше и написал.
          • 0
            Можно внутренний уарт вывести как у меня — habrahabr.ru/post/153017
          • 0
            Ой сори, вы об этом ниже пишете.
      • 0
        А и не нужно одновременно — конденсаторы (для задержки) + простые тригеры и никакого стробирования — все семь нагрузок ваши…
        • +1
          Сдвиговый регистр. Одна линия на клок, вторая на данные, третья — обновить состояное выходов. Так можно сколько угодно нагрузок подключить. Да, я только что изобрел serial to parallel конвертер :)
  • 0
    Скажите что за замочек у вас?
    • 0
      Точно не знаю, но внешне похож на Полис-16. Висел без дела, вот и попался под эксперимент.
  • 0
    Я тоже купил MR3020 отличный девайс!
    В настоящий момент тоже провожу с ним эксперименты
    • +2
      Если еще не вывели из него serial — настоятельно советую. Я уже пару раз лишал коробку выхода во внешний мир играми с сетевыми интерфейсами. Если бы не сериал — было бы грустно. И встает разъем в коробочке чудо как хорошо:



      Умный дом — тема мне очень интересная. Думаю сделать шлюз из сети в X10 так как дома уже стоит пара-тройка X10-устройств. Хотя будущего у X10, очевидно, нет.
      • 0
        Хорошее решение
        Только я уже прямой разъем припаял. :(
      • 0
        Это что за разъем?
        • 0
          UART
          • 0
            Прикольно, не знал что UART еще стандарт разъемов.
            • +2
              Штыревой разъем на плате обычно называют PLS-4R (можно взять хоть PLS-40R и отломить нужное количество штырьков); кабель заделан в BLS-5 — специально взял на одно гнездо больше и заткну крайнее отверстие, чтобы можно было вставить разъем только одним образом. Что же касается стиля вашего вопроса, и особенно комментария к нему — напомнило вот это: "… можно попросить о помощи, и, выслушав рекомендации, объявить их ламерскими и глупыми… можно попросить обосновать данные советы… путём… уточнения подробностей, которые, в идеале, делают предлагаемые решения неправильными, а ещё лучше вредными." Описание технологии троллинга, кстати.
              • 0
                :) Спасибо за разъяснение. Но я действительно не был уверен, т.к. эта область нова для меня. Прошу прощения за неудачный стиль
    • 0
      Испортил я свой MR3020, хотел заменить микросхему оперативы на 64мГб
      В итоге при выпаивании старого чипа оторвал 5 дорожек :(
      Купил TL-WR70N, заменил оперативу, пока полет нормальный
      • +1
        А я свой так и вообще найти не нигде не могу. Прям как в анекдоте — «один сломал, другой — потерял» :-). Вот они, минусы маленькой коробочки!
        • 0
          А ты по SSH у него спроси, куда он спрятался :-)
  • +2
    Не хватает ссылки на более дешевый локально-китайский вариант MR3020 (от той же фирмы TP-LINK, с совершенно аналогичным железом внутри)
    TL-WR703N wiki.openwrt.org/toh/tp-link/tl-wr703n
    и где купить searchsku.ru/s?q=WR703N
    • +1
      Не хочу никого обидеть, но экономия 100-150 рублей в обмен на месячное ожидание — вопрос спорный. Хотя, конечно, если живешь не в Москве, а скажем, в Хабаровске — экономия может быть и больше. Время доставки, думаю, не изменится — один черт через Москву пойдет (.
  • +1
    Я так смотрю что этот роутер нашими совместными усилиями будет делать странно большую прибыль у компании. Их маркетологи себе все мозги сломают отчего такой спрос.)))) А идея про клаву однозначно зачет!
    • 0
      Вот бы они догадались сами встроить в них опторазвязки… Чтоб так колдовать не приходилось…
  • 0
    Использование недорогих роутеров в домашней автоматике весьма интересная тема. Правда, сам я привык всё-таки к Arduino и попытался собрать универсальный wifi-модуль на DIR320+Arduino. Там правда ещё «пилить и пилить»… А эту статью, одназначно, в «закладки» идей на будущее :)
    • +1
      Тплинк + Ардуино тоже хорошо и главное не так громоздко habrahabr.ru/post/153017
    • 0
      Господа, многие, думаю, согласятся, что эта коробочка — просто сказка. Но неприятность в том, что нам неизвестно, когда производитель вздумает прекратить ее производство. Хотелось бы иметь альтернативу, желательно с открытым дизайном, чтобы базировать на ней свои поделки. Существует ли что-то подобное?
      • 0
        Если принципиальна открытость, то можно рассматривать те же открытые контроллеры а-ля arduino и ethernet-shield-ы к ним. Я думаю, что использование таких «закрытых» коробочек оправдано именно из-за их стоимости. Да и риск того, что производитель перестанет их производить не так уж страшен — вы же не в коммерческих масштабах на них полагаетесь, а для своих поделок всегда можно найти альтернативы…
      • +1
        Существует. Идентична этому роутеру по железу полностью, только флеш на 8 метров. Ну и выведены ГПИО, но нет стабилизаторов на борту. Опенсорсно, удобно. Все решения для роутера без портирования должны стартовать и на ней. Единственное, почему я выбрал роутер а не эту плату — цена за доставку+ожидание, а так она даже по цене почти такая же.
        • 0
          Обманул немного, видимо перепутал — процессор стоит не Атерос, а РаЛинк, но в целом по железу очень похожа, те же частоты, объем рам, сравнимый порядок размера флеша и возможности.

          Стаб на борту на 3.3 таки есть.
      • 0
        Ничего страшного не случится. Если открыть страницу поддерживаемого оборудования open-wrt там роутеров великое множество. И думаю новые модели будут тоже перепрошиваемы. А так же Raspberri Pi это ведь тоже только начало, аналогов будет море.
      • 0
        Тут целый список сказочных коробочек
  • +1
    Ностальгия :)
    2006г. Продукт — электронная очередь, причём сенсорные экраны в те времена были ещё недостаточно освоены, чтобы ставить их повсеместно. Работали с обычными механическими кнопками. Устраиваюсь программистом.
    В какой-то момент закончились контроллеры для кнопок. А выглядели они знатно: собственно контроллер <---> переходник RS485-COM <---> переходник COM-usb + внешний блок питания от 220В. Партия придёт через неделю, под рукой мышка.
    Самой трудной задачей было понять, почему не стали использовать мышку раньше, а далее 10 минут с паяльником и отвёрткой, полдня на добавление нового функционала в проект и стоимость нашего «контроллера кнопки» снизилась с 200$ до 200 рублей + 10 минут на раскручивание корпуса мышки и припаивания к нему проводов от кнопки. Плюсом стало, что такой контрголлер занимал намного меньше места)
    • +1
      Ты испортил кому-то кормушку стопудово:)
      • 0
        Нет, правда что ли, $200 на одну кнопку???
        • 0
          Первые были по 200$, потом отыскали по 100$ спаянные где-то на коленке. Зато пооддерживали они до 50ти разных входов, а у тех, что по 200$ были ещё и ЖК экранчики. Только максимум того, что от них требовалось даже в теории — это 5 кнопок. Ну а тех, кому я испортил кормушку к моему приходу уже успели уволить.
  • 0
    Еще вот есть вариант: берем готовый Mikrotik RB750UP(2200руб) + Розетка управляемая SNR-SMART-DIN-A(550руб) и по инструкции — получаем от 1 до 4 управляемых розеток. Просто вроде и работать должно.
  • 0
    А как защитить паролем веб-интерфейс с переключателями?
    • 0
      Чтобы случайно-зашедший кулхацкер со сканером портов не баловался?
      • 0
        Например так
        • 0
          поддерживает ли uhttpd htaccess. но вот Basic Authentication я думаю полюбому должна быть
      • 0
        Правильный и актуальный вопрос. Для защиты от пубертатных кулхацкеров, можно предпринять следующее: 1) использование нестандартных портов, (так как обычно они тыкаются своими рыльцами в стандартные 21, 22, 80, etc. и дальше этого не идут) 2) использование хотя бы примитивной аутентификации (добавил рецепт в конце статьи). Но, конечно, эта защита не выстоит в случае направленной атаки. Вот почему я не стал бы в реальной жизни управлять замком так, как я демонстрирую это в видео.
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Привод от стеклоподъемника автомобиля вам в помощь. При смене полярности откатывается назад.
      • 0
        Но правильнее использовать питание на сервере через нормальнозамкнутое реле
        • 0
          Разве при нажатии кнопки питания на сервере происходит полное обесточивание? Я не знаю ничего о серверах, но для обычных компьютеров это не так.
          • 0
            Может, вместо (или параллельно) кнопки питания и поставить реле?
            • 0
              Кажется более разумным, но, думаю, проблема может быть в том, что вмешиваться во внутренности сервера крайне нежелательно, даже по минимуму. Именно поэтому автору комментария, возможно, нужен «палец».
  • 0
    Спасибо за интересное решение!
    Я не вдаваясь в подробности, прошил свой роутер прошивкой CyberWrt
    И за два клика протестировал работу контроллера клавиатуры
    Планирую управлять рольставнями
  • 0
    Похожую проблему решает такой предмет:
    energenie.com/item.aspx?id=7678
    • 0
      Или такой. Заказал, посмотрим, что за зверь.

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