среда, 11 января 2017 г.

Ещё один Wi-Fi выключатель из песочницы


Данная статья будет посвящена ESP8266 Wi-Fi модулю, языку программирования Lua и прошивке nodeMCU. SDK от производителя рассматриваться не будет.

Примерно года три назад я пробовал реализовать выключатель по 1-wire шине. Как все работало мне очень не понравилось.

  • Единая точка отказа т.к. вся логика на сервере;
  • Медленная скорость;
  • К каждому выключателю придется тянуть от 2х проводов(идеально «витуху»).


В следствии чего все это было удачно заброшено, другие беспроводные решения рассматривались, но были исключены в виду дороговизны, небезопасного протокола и сложности реализации. Хотелось чего то простого с минимумом компонентов, со своей логикой и дешёвого. Не давно заказал 2 штуки esp8266 просто для забавы, не зная, чего конкретного с ними можно сделать. После 2-х вечеров разборок с чипом вспомнил незавершённое дело с кнопкой и решил довести до логического конца.

На данный модуль уже существует некоторое количество прошивок, так же вы можете писать прошивку под себя, используя SDK, но не стал вникать в подробности написания, т.к. после изучения API nodeMCU понял, что данного функционала мне хватает с запасом и прошил оба модуля.

Железо


Себестоимость важный фактор для простого выключателя, так что пытался использовать как можно меньше частей. Решил сделать из того что было дома, но пришлось купить твердотельное реле. Кстати, «релюшка» стоит дороже wifi модуля и ее можно заменить на оптопару, симистор и обвязку, схемы включения легко ищутся в интернете. Был случай, когда плохой контакт в патроне лампочки выбил симистор на коротко. Посмотрим, как покажет себя оптореле, ведь раньше с ними не работал. Стоит учесть для большой нагрузки установка радиатора обязательна.

Тут сразу столкнулся с проблемой, если на gpio при включении он уходил на землю, плата переходила или в режим прошивки или в непонятный режим, т.к кнопка у нас нормально разомкнута, с ней переделывать нечего не стал и так и оставил замыкаться на землю, а оптореле повесил на плюс через резистор и включал подачей 0, выключал подачей 1, соответственно. В итоге получилась такая схема:



Внимание схему стоит улучшить! Выход на реле стоит подать через транзистор, а кнопку подтянуть через резистор от плюса. Ингредиенты получились такие:

  • выключатель;
  • пружинка(для переделки выключателя в кнопку);
  • сам esp8266;
  • твердотельное реле использовал(S202T02);
  • платка для конструирования;
  • резистор 470 Ом;
  • провода;
  • разъемы по вкусу;
  • зарядка от телефона 400мА 5v;
  • стабилизатор 1117 3.3v;
  • пара конденсаторов.


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







nodeMCU


Прошивка использует Lua язык программирования, данный язык похож чем то на Javascript. Версия ещё сыроватая, но уже базовый функционал вполне не плохо реализован. Сразу после загрузки модуль начинает исполнять файл скрипт init.lua, в чистой прошивке этого файла нет, вам приходиться его создать руками. Все операции можно осуществлять через консоль подключенным к «com» порту, для упрощения заливки файлов в модуль есть скрипт luatool. Заливка работает следующим образом и данный код полностью показывает процесс записи в файл.

file.open("init.lua","w")
file.writeline([[print("Hello World!")]])
file.writeline([[--comment]])
file.close()


Пример чтения конфигурационного файла. Выглядит не очень. Может есть и другой вариант сериализованных данных.

file.open('config')
c_wifi_ssid = string.gsub(file.readline(), "\n", "")
c_wifi_key  = file.readline()
file.close()


Пример цикла с использованием API с паузой в 1000 миллисекунд представлен ниже:

tmr.alarm(1000, 1, function()
  if wifi.sta.getip()=="0.0.0.0" then --текущий ip
    print("connecting to AP..."..c_wifi_ssid.."/"..c_wifi_key)  
  else
    print('ip: ',wifi.sta.getip())
    tmr.stop() -- alarm stop
  end
end)


Работа с GPIO

Если у вас модель модуля ESP-01 новой ревизии, то вам доступно всего 2 gpio, не прибегая к грязному хаку.



Решил отказаться от такого хака и воспользоваться тем, что есть.

Один gpio кнопка и второй выход на твердотельное реле. Есть еще Tx, но заставить работать как gpio у меня не получилось, и для индикации я просто передаю сообщения в консоль print(). Пока закостылил именно так. Чем длиннее сообщение, тем дольше и ярче вспыхивает светодиод. Владельцы данной модификации пролетают лесом и с такими функциями как (node.key, node.led), т.к. они могут использовать только GPIO16, который тоже не разведен на плате.

Все gpio могут работать в нескольких режимах (OUTPUT, INPUT, INT), но интересно то, что функция gpio.read(), прежде чем считать, подает низкий уровень, даже если установлен режим OUTPUT. То есть, чтобы получить текущее состояние выхода, это не подходит. Пришлось использовать внешнюю переменную и писать две функции для удобства, а уже через переменную определять активность.

function on()
  gpio.write(8,gpio.LOW)
  oo=1
end

function off()
  gpio.write(8,gpio.HIGH)
  oo=0
end


В качестве событий можно использовать callback gpio.trig(pin, type, function(level)), второй параметр может принимать следующие значения «up», «down», «both», «low», «high». Тут, кажется, все ясно. Если у вас вывод находится в состоянии 1 и мы его опускаем на землю, срабатывает down, потом при поднятии срабатывает up, но, к моему сожалению, такого не происходило, в консоли я видел только down в зависимости от скорости нажатия кнопки событие срабатывало 1 или 2 раза. Решил поставить цикл с паузой и бряк по 1 на gpio.

for i=1,1000 do
  print(i)
  tmr.delay(10)
  tmr.wdclr()   -- сбрасывает счетчик и предотвращая авто перезагрузку
end


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

function down()
  tmr.alarm(100, 1, function()
    timer = timer + 1
    -- ok
    if gpio.read(9) == 1 then
      print(timer)
      tmr.stop()
      if timer < 20 then
        switch()
      else
        -- ...
      end
      timer = 0
    end
    tmr.wdclr()
  end)
end
gpio.trig(9, "down", function (gp)
  if timer == 0 then
    timer = 1
    down()
  end  
end)


HTTP сервер

Сервер запускается как 2 пальца, но никакого массива параметров запроса не получите. Пока непонятно, как оптимальнее: или писать свой велосипед, или find по подстроке. Согласитесь, выглядит ужасно. В данном примере ищется 2 параметра key и mode=off,on,party. Последний режим – это простое мигание лампочкой каждые 200мс, можно поставить и побыстрее, но побоялся за лампочку и оптореле.

function HTTPd()
  print('start http serv')
  srv=net.createServer(net.TCP, 5)
  srv:listen(80,function(conn)
    conn:on("receive",function(conn,payload)
      print(payload)

      if string.find(payload, "key="..c_api_key) then
        msg = "key_ok"      
        if string.find(payload,"mode=on") then
          on()
        else
          if string.find(payload,"mode=off") then
            tmr.stop()
            off()
          else
            if string.find(payload, "mode=party") then
              party(200)
            end
          end
        end
      else
        msg = "error_key"
      end
      conn:send("

mode=[on,off,party] key='api_key'

"
..msg.."
") end) conn:on("sent",function(conn) conn:close() end) end) end

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

Wi-Fi

Для подключения в качестве клиента хватит такого кода, ip получим по DHCP:

wifi.setmode(wifi.STATION)
wifi.sta.config(c_wifi_ssid,c_wifi_key)
wifi.sta.autoconnect(1)


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

В целом, с небольшими хитростями (костылями) была написана логика простого выключателя. А кнопкой можно управлять прямо из консоли. Поставив программу BetterTouchTool, можно комбинацией клавиш «curl`ить» сервер выключателя. Нашлось применение кнопке EJECT.

Резюме


Нисколько не жалею, что выбрал nodeMCU: не пришлось залезать в дебри официального SDK. Не надо каждый раз компилировать код, а саму программу легко разбить на модули и заливать отдельными кусочками. За это пришлось поплатиться иногда непонятным поведением. Главное, что вся логика находится на самом выключателе, и он при недоступности wifi будет выполнять свою главную функцию, ну, только если сгорит. Самому проекту nodeMCU я желаю скорейшего развития и в дальнейшем попробую сделать что-нибудь ещё, благо остался еще один модуль.

Полезные ссылки

Настройка и использование OpenBox Window Manager

Дата публикации: April 10, 2010, 12:56 p.m.
Теги: openbox, настройка,
Автор: Brainsburn

Краткое содержание: Настройка меню OpenBox; автозапуск программ в OpenBox; установка тем оформления; установка фона рабочего стола; панель задач и системный трей; лаунчер программ; горячие клавиши и мультимедиа клавиатура в OpenBox.


Решил я сменить свой FluxBox на что-нибудь другое. Единственная причина - известный баг, при котором многие флэш-анимации (если честно, ненавижу флэш) на сайтах не реагируют на нажатие кнопок мыши. Частично эта проблема решалась прописыванием export GDK_NATIVE_WINDOWS=1 в ~/.bashrc , но все-равно на многих сайтах проблема оставалась.
FluxBox меня радовал всем. Быстрый и незаметный - вот каким должен быть оконный менеджер, на мой взгляд. Я пробовал динамические тайловые оконные менеджеры типа Awesome и Xmonad но, как говорится, это не мое. Поэтому, когда от FluxBox пришлось отказываться, мой выбор пал на OpenBox.
Установив OpenBox командой emerge openbox и добавив строку openbox вместо строки startfluxbox в файл ~/.xinitrc (чтобы OpenBox запускался по startx), и перезапустив иксы, я попал (куда бы вы думали?) в дефолтный опенбокс. Возможно, если бы вместо FluxBox у меня был установлен KDE или Gnome, я бы испугался такому виду - черный экран, нету даже панели задач и лишь меню, появляющееся по правому клику мыши, дает понять, что это именно OpenBox. Но, это пройденный этап - мы видали и не такое ;)
В первую минуту был обнаружен глюк - окно Conky стало отображаться поверх всех остальных окон. Вылечился он очень быстро - в ~/.conkyrc надо было заменить строку own_window_type override на own_window_type normal

Настройка меню OpenBox

Первым делом было решено настроить меню. Для этой цели я решил воспользоваться графической утилитой obmenu (устанавливается отдельно). Я скопировал дефолтный конфиг в домашнюю директорию и запустил obmenu
$ mkdir ~/.config/openbox && cp /etc/xdg/openbox/menu.xml ~/.config/openbox/menu.xml
$ obmenu
Эта утилита ничего не делает автоматически, она всего-лишь позволяет отказаться от копания в XML коде. Кстати, после добавления нового меню, не забудьте добавить link на это меню в рутовое меню "Openbox 3", иначе ваше новое меню не будет отображаться. Чтобы изменения вступили в силу, нужно сохранить меню в Obmenu и выбрать System - Reconfigure Openbox в основном меню OpenBox, перезапускать иксы не нужно =)

Автозапуск программ в OpenBox

При запуске иксы смотрят файл ~/.xinitrc . Если его у вас нету - создайте. В него можно прописывать команды для тех программ, которые нужно запускать автоматически. Вот пример:
$ cat ~/.xinitrc
psi &
qutim &
conky &
xxkb &
feh --bg-scale /files/Pictures/Абстракции/organic.jpg &
tint2 &
openbox
Обратите внимание - команда openbox идет последней и после всех команд, идущих перед ней, стоит символ &. Если в этом примере "tint2 &" изменить на "tint2", то openbox не запустится, пока не завершится процесс tint2.

Установка фона рабочего стола в OpenBox

Знаете, возможно существуют удобные программки для быстрой смены фона на рабочем столе с GUI и всякими плюшками, но я меняю фон не чаще чем раз в месяц (раньше менял чаще, со временем это прошло), поэтому для установки обоев я воспользовался утилитой feh:
$ feh --bg-scale /files/Pictures/Абстракции/organic.jpg
Эту же команду нужно добавить в ~/.xinitrc , тогда нужный вам фон будет устанавливаться каждый раз при запуске иксов. Причем этот способ не привязан к оконному менеджеру и будет работать везде.

Установка тем оформления в OpenBox

Я уже было приготовился открывать конфигурационный файл в текстовом редакторе, но обломался - почти во всех мануалах советуют использовать графическую утилиту obconf, которая позволяет удобно менять темы оформления, устанавливать новые темы да и вообще конфигурить OpenBox под собственные нужды. Через нее можно сделать, чтобы по двойному клику на заголовке окна оно привычно сворачивались в заголовок вместо разворачивания на весь экран; изменить шрифты, изменить кол-во рабочих столов и т.д. Довольно удобная тулза :)

Панель задач и системный трей в OpenBox

Из самых популярных я выделил бы PyPanel, Tint2 и fbpanel. Последняя мне показалось слишком навороченной, поэтому ее я отложил в сторонку. PyPanel довольно легка и хороша, но мне больше понравилась Tint2, уж не знаю почему. Пользователи Gentoo при установке Tint2 могут выбрать флаг examples, тогда tint2 установится вместе с несколькими примерами конфигурационных файлов, которые будут лежать в /usr/share/doc/tint2-0.9/examples/ . Дефолтный файл конфигурации tint2 называется ~/.config/tint2/tint2rc . Конфиг очень прост и интуитивен - мне хватило пяти минут, чтобы методом тыка привести tint2 панель в нужный мне вид. Для того, чтобы tint2 стартовала автоматически, я добавил строку tint2 & в ~/.xinitrc .

Лаунчер программ в OpenBox

В FluxBox лаунчер был сразу и вызывался сочетанием alt-F2. В OpenBox его надо ставить отдельно. Посоветую или grun или gmrun. Как сделать, чтобы они вызывались по сочетанию клавиш, читайте ниже в части "Горячие клавиши в OpenBox"

Горячие клавиши в OpenBox

Сочетания горячих клавиш настраиваются в ~/.config/openbox/rc.xml Ctrl-Alt-Left - переместиться на предыдущий рабочий стол
Ctrl-Alt-Right - переместиться на следующий рабочий стол
Shift-Alt-Left - переместить активное окно на предыдущий рабочий стол
Shift-Alt-Right - переместить активное окно на следующий рабочий стол
Windows-F1..F4 - перейти на нужный рабочий стол (1..4)
Настраиваются горячие клавиши в разделе keyboard Для того, чтобы по Alt-F2 вызывался лаунчер gmrun, добавьте в этот раздел следующие строки:
 key="A-F2">
 name="Execute">
gmrun


Остальные программы биндятся аналогично. Запомните - вместо Alt пишите A, вместо Ctrl - C, вместо Windows - W, вместо Shift - S
В моем дефолтном конфиге OpenBox не было таких биндингов как Alt-F10 для распахивания окна на весь экран и Alt-F9 для сворачивания. Привожу примеры бинда клавиш для управления окнами:
Переключатель Распахнуть окно на весь экран
 key="A-F10">
 name="ToggleMaximizeFull"/>


Переключатель Максимизировать окно по вертикали
     key="A-F8">
           name="ToggleMaximizeVert"/>
              

Свернуть окно в панель задач
     key="A-F3">
           name="Iconify"/>
              

Переключатель Максимизировать окно по горизонтали
     key="A-F9">
           name="ToggleMaximizeHorz"/>
              

Переключатель Растянуть содержимое окна на весь экран
     key="A-F12">
           name="ToggleFullscreen"/>
              

Переключатель Снять/Показать декорации окна
     key="A-S-d">
           name="ToggleDecorations"/>
              

Мультимедиа клавиатура и OpenBox

Во FluxBox я назначал мультимедиа клавиши в файле ~/.fluxbox/keys , узнавая код клавиш утилитой xev. В OpenBox есть одна тонкость - код клавиш нужно перевести в 16-ричную систему счисления. Например, вы хотите забиндить какую-то мультимедиа клавишу на увеличение громкости звука ALSA. Запускаете в терминале утилиту xev, нажимаете нужную клавишу и смотрите ее keycode. Там будет что-то вроде этого:
KeyRelease event, serial 39, synthetic NO, window 0x1e00001,
root 0x15a, subw 0x0, time 1613305, (627,558), root:(655,831),
state 0x0, keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume),
same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
Жирным текстом выделено нужное. Теперь это число (122) нужно перевести в 16-ричное. Делается это просто:
$ printf "%X\n" 122
7A
К этому числу нужно добавить спереди "0x", т.е. получится "0x7A". Теперь, используя этот код клавиши (0x7A), биндите клавишу как обычно:
 key="0x7A">
 name="Execute">
amixer sset Front 1+




Ну и под конец привожу краткий список софта, который пригодится тем, кто использует WM вместо DE.
Настройка OpenBox - obconf, obmenu и... vim =))
Использование темы GTK для Qt программ - qtconfig.
Выбор темы GTK - gtk-theme-switch
Панель задач и системный трей - PyPanel, fbpanel или tint2
Автоматическое монтирование флешек и CD/DVD дисков - ivman или autofs
Лаунчер (запуск программ по Alt-) - grun или gmrun
Установка фона рабочего стола - консольный feh или графический nitrogen
Отдельная раскладка клавиатуры для каждого окна - xxkb
Создание скриншотов - scrot
Логин менеджер для иксов - Slim


Администрирование → Видеонаблюдение загородом посредством 3G интернета из песочницы tutorial

Появилась такая задача: Установить видеонаблюдение, в 15 км от города, где доступен только gprs интернет.
Условия:
  • Камерами можно будет управлять через интернет
  • Ограниченный бюджет
  • В городе есть 3G интернет но в области нет.
  • Сотовые операторы не дают «Белый и статический ip адрес».
  • Другого интернета нет.


Что бы решить данную задачу я решил построить такую сеть.
Взять самый дешевый сервер VDS. Недорогой роутер TP-LINK MR 3420, 3G модем от beeline, ip камеру. И построить такую сеть как на схеме.
Суть идеи такова: На сервере поднимается openvpn сервер, на роутере поднимается openvpn клиент, далее объединяем локальную сеть с сетью openvpn. Затем пробрасываем необходимые порты на сервере.



Описание сети:
Первая сеть это роутер + ip камера + ваш компьютер (шлюз). Адрес сети будет 192.168.0.0
У роутера 192.168.0.1
У камеры 192.168.0.100
У вашего компьютера, который будет шлюзом 192.168.0.2

Вторая сеть, это сеть openVPN – 192.168.3.0
IP адрес openVPN вашего роутера будет 192.168.3.2
IP адрес вашего сервера будет 192.168.3.1

И внешний ip адрес сервера для примера будет 205.234.139.100

Что нам нужно.
  1. Компьютер.
  2. Временный доступ в интернет через компьютер.
  3. Роутер который поддерживает OpenWRT и 3G usb модема. (для примера TP-LINK MR 3420)
  4. Сервер с внешним ip адресом на базе Linux.
  5. 3G usb модем (Я использовал Huawey).
  6. IP Видеокамера.
  7. Хороший USB хаб, с внешним питанием (Для расширения USB портов для 3G модема и флэшки).


Ход работы.
  1. Настраиваем на сервере openVPN, генерируем ключи для клиента openVPN.
  2. Настраиваем на роутере openWRT + openVPN и 3G модем для выхода в интернет.
  3. Если 3G связь ловит плохо, собираем антенну Харченко для усиления сигнала.


Настройка openVPN на сервере.

Как настроить сервер openvpn, до пункта “Объединение сетей”, описано тут: Настраиваем OpenVPN сервер на подключения клиентов

Конфигурация сервера выглядит примерно так:

daemon
local 205.234.139.100 # Внешний ip сервера
port 1194
mode server
proto tcp
crl-verify crl.pem
dev tap
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
client-config-dir ccd
server 192.168.3.0 255.255.255.0 # ip самого openvpn
push "route 192.168.3.0 255.255.255.0"
ifconfig-pool-persist ipp.txt
keepalive 10 120
comp-lzo
persist-key
persist-tun
client-to-client
status openvpn-status.log
log /var/log/openvpn.log
verb 3

Чтобы каждому клиенту выдавался определенный ip адрес, в конфиге есть строчка
ifconfig-pool-persist ipp.txt

Создаем на сервере документ в папке /etc/openvpn/
Под названием ipp.txt
nano /etc/openvpn/ipp.txt

И в нем пишем “имя клиента, ip адрес”
Например вот так
openwrt,192.168.3.2


Прошивка и настройка роутера TP-LINK MR3420.

Как прошить роутер описано по ссылке: TP-Link TL-MR3420 & TL-MR3220

Для начало нужно дать выход роутеру в интернет для установки дополнительного ПО.

Для того что бы роутер мог выйти в интернет заходим через web (http://192.168.1.1), заходим в network. Далее жмем edit в lan
Переходим на вкладку General Setup и изменяем ip локальное сети на
IP адрес: 192.168.0.1
Маска: 255.255.255.0
Шлюз: 192.168.0.2
DNS: 8.8.8.8



Для того что бы изменения вступили в силу, жмем «Save & Apply»
На компьютере поставим себе ip 192.168.0.2, и используем его как шлюз.

Теперь нужно расширить память роутера для установки дополнительного ПО.
Для этого берем флэшку (Например 4 Гб) и форматируем ее с файловой системой ext4.
Затем вставляем ее в USB хаб и подключаем к роутеру USB хаб.
Потом нужно перенести все настройки на флэшку и сделать что бы она сама монтировалась при старте.

Устанавливаем пакеты для флэшки:
opkg update
opkg install kmod-usb-uhci kmod-usb-storage block-mount kmod-fs-ext4
insmod usb-ohci

Создаем точку подключения:
mkdir /mnt/sda

Затем монтируем флэшку:
mount -t ext4 /dev/sda /mnt/sda -o rw,sync

Копируем туда установленные пакеты:
tar -C /overlay -cvf - . | tar -C /mnt/sda -xvf –

Немного правим конфиг:
vi /etc/config/fstab

Чтобы выглядело вот так:
config 'mount'
option target /overlay
option device /dev/sda
option fstype ext4
option options rw,sync
option enabled 1
option enabled_fsck 1

Затем перезагружаем роутер:
reboot

Теперь мы не ограничены исходным размером flash роутера. И можем себе позволить поставить практически все
Смотрим свободное место:
df –h

Filesystem                Size      Used Available Use% Mounted on
rootfs                    3.7G    128.2M      3.4G   4% /
/dev/root                 2.0M      2.0M         0 100% /rom
tmpfs                    14.3M    688.0K     13.6M   5% /tmp
tmpfs                   512.0K         0    512.0K   0% /dev
/dev/sda                  3.7G    128.2M      3.4G   4% /overlay
overlayfs:/overlay        3.7G    128.2M      3.4G   4% /

Теперь нам нужно установить openvpn клиент на роутер, заодно и текстовый редактор nano, файловый мэнеджер mc, и русификатор luci.

Устанавливаем необходимые нам пакеты:
opkg install openvpn nano mc luci-i18n-russian

Для нормальной работы mc нужно выполнить две строчки:
export TERMINFO=/usr/share/terminfo
export TERM=xterm

И чтобы каждый раз их не выполнять руками нужно их добавить в /etc/profile:
nano /etc/profile

Затем копируем на роутер в /etc/openvpn/ ключи и сертификаты созданные на сервере openvpn:
ca.crt
dh1024.pem
openwrt.crt
openwrt.key
ta.key

Правим конфиг:
nano /etc/config/openvpn


client
tls-client
dev tap
proto tcp
remote 205.234.139.100 1194 # Вашь Ip и порт сервера
resolv-retry infinite
nobind
persist-tun
persist-key
ca /etc/openvpn/ca.crt
cert /etc/openvpn/openwrt.crt
key /etc/openvpn/ openwrt.key
dh /etc/openvpn/dh1024.pem
comp-lzo
verb 3

Запускаем openvpn:
openvpn --config /etc/config/openvpn

Если ваше Интернет-соединение в порядке и конфигурационный файл openvpn составлен правильно, вы должны увидеть такую надпись:
  • Initialization Sequence Completed

Если вы хотите, чтобы vpn-соединение восстанавливалось после каждой перезагрузки маршрутизатора, добавьте эту строку в /etc/rc.local перед строкой exit 0:
openvpn --config /etc/config/openvpn  &
exit 0 

Объединим сети 192.168.0.0 и 192.168.3.0:
Ваш ip сервера openvpn 192.168.3.1, а ваш Ip на роутере openvpn адаптера tap0 192.168.3.2

Тогда что бы ваш сервер смог увидеть вашу локальную сеть (192.168.0.0) нужно на сервере прописать маршрут.
ip route add 192.168.0.0/24 via 192.168.3.2

Теперь вашу локальную сеть на роутере вид ит сервер с openvpn.

Настроим проброс порта:

Допустим ваша ip камера работает по порту 99, тогда чтобы пробросить порт камеры или другого сетевого устройства пропишем такие строки в консоли, или как описано ниже создаем файл и пишем в него:
EXT_IP="205.234.139.100" # Вашь сервер ip
INT_IP="192.168.3.1"           # Локальный шлюз (ip tap0)
EXT_IF=venet0:0                   # Сетевая карта внешнего ip
INT_IF=tap0                           # Сетевая карта openvrt
LAN_IP="192.168.0.100"    # ip на который нужно пробросить порт
SRV_PORT=99       # Порт который нужно пробросить

iptables -t nat -A PREROUTING --dst $EXT_IP -p tcp --dport $SRV_PORT -j DNAT --to-destination $LAN_IP
iptables -t nat -A POSTROUTING --dst $LAN_IP -p tcp --dport $SRV_PORT -j SNAT --to-source $INT_IP
iptables -t nat -A OUTPUT --dst $EXT_IP -p tcp --dport $SRV_PORT -j DNAT --to-destination $LAN_IP
iptables -I FORWARD 1 -i $EXT_IF -o $INT_IF -d $LAN_IP -p tcp -m tcp --dport $SRV_PORT -j ACCEPT

Теперь вы можете конектится к ip камере по адресу 205.234.139.100:99.
А чтобы не делать это вручную после перезагрузки сервера, создадим скрипт, в папке /root/ файл с названием start
и дадим ему права на выполнения:
chmod  777 /root/start

Затем добавим строку в /etc/crontab
@reboot root /root/start

Теперь после перезагрузки сервера скрипт автоматически запустится.

Установка usb 3g Ethernet модема от huawey

opkg update
opkg install usb-modeswitch usb-modeswitch-data kmod-usb-net-cdc-ether

Вставляем модем в USB хаб,
И пишем команду dmesg, вы должны увидеть примерно такие строки:
 [   99.220000] usb 1-1.1.1: new high-speed USB device number 6 using ehci-platform
[   99.330000] cdc_ether 1-1.1.1:1.0: eth2: register 'cdc_ether' at usb-ehci-platform-1.1.1, CDC Ethernet Device, 58:2c:80:13:92:63

Это говорит о том что модем установлен и определился как eth2.

Следующим шаом нам нужно добавить 2 сетевых интерфейса.
1. 3G
2. VPN
для этого правим конфиг:
nano /etc/config/network

3G у нас будет DHCP клиентом, а VPN неуправляемым адаптером, добавляем:

config interface '3G'
        option ifname 'eth2'
        option _orig_ifname 'eth2'
        option _orig_bridge 'false'
        option proto 'dhcp'

config interface 'VPN'
        option ifname 'tap0'
        option _orig_ifname 'tap0'
        option _orig_bridge 'false'
        option proto 'none'

В общем виде конфиг должен выглядеть примерно так:
config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config interface 'lan'
        option _orig_ifname 'eth0 wlan0'
        option _orig_bridge 'true'
        option proto 'static'
        option netmask '255.255.255.0'
        option type 'bridge'
        option ipaddr '192.168.0.1'
        option ifname 'eth0'
        option send_rs '0'

config interface '3G'
        option ifname 'eth2'
        option _orig_ifname 'eth2'
        option _orig_bridge 'false'
        option proto 'dhcp'

config switch
        option name 'eth0'
        option reset '1'
        option enable_vlan '1'

config switch_vlan
        option device 'eth0'
        option vlan '1'
        option ports '0 1 2 3 4'

config interface 'VPN'
        option ifname 'tap0'
        option _orig_ifname 'tap0'
        option _orig_bridge 'false'
        option proto 'none'


Что-бы сервер мог видеть все 3 сети, нужно их объединить в межсетевом экране

Для этого изменим файл /etc/config/firewall
nano /etc/config/firewall

nano /etc/config/firewall

Сделать примерно так:
config defaults
        option syn_flood '1'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'

config include
        option path '/etc/firewall.user'

config zone
        option name 'newzone'
        option input 'ACCEPT'
        option forward 'ACCEPT'
        option output 'ACCEPT'
        option masq '1'
        option network '3G lan vpn'


И делаем перезагрузку роутера
reboot


Усиления 3G сигнала на модеме.

Для того чтобы увеличить сигнал 3G модема нужно собрать антенну Харченко.
Обычно, популярные 3G модемы работают на частотах от 800 до 2100 МГц.

Делается это просто.
Нам потребуется:
  • Провод RG6U (толстый белый для антенн – на нем меньше всего затухания) метров 6
  • Коннектор на него
  • Кусок медной проволоки от 1 до 4 мм толщиной ( у меня 1.5)
  • Колпачок от пены для бритья.
  • Паяльник, припой, канифоль и немного навыков работы с ними.
  • Кусок фанерки (120мм на 134мм) и фольга. Либо не травленая плата, покрытая медью с одной стороны.

Начнем.
  • Берем кусок нашей проволоки и сгибаем его в два квадрата, как показано на рисунке. Сторона квадрата должна быть 53мм
  • Концы двух квадратов спаиваем вместе, чтобы получилась сплошная конструкция, наносим припой также на противоположный угол

image

  • Антенный провод зачищаем и надеваем на него коннектор, делаем сердцевину провода так чтобы она выглядывала из коннектора на сантиметр
  • Припаиваем сбоку к телу коннектора кусочек сердцевины провода ( так как не всегда удается припаять оплетку провода с помощью канифоли)
  • После этого припаиваем оба штырька, идущие от коннектора к нашим квадратам

image

  • Теперь делаем рефлектор для лучшего приема — берем нашу фанерку 120 на 135 мм и оборачиваем ее в фольгу, делаем в середине дырку под провод.
  • Сам каркас антенны из проволоки должен находиться над рефлектором на расстоянии 35мм, для этого берем колпачок от пены для бриться или что-то похожее. Он по высоте 4.5 см, поэтому вырезаем в нем пазы в 1 см, чтобы антенна была от рефлектора на нужном расстоянии.

image

  • Сзади всей этой конструкции подставляем рефлектор, сделанный нами ранее и получается готовая антенна:

image

Следующим шагом нужно припаять другой конец провода к модему:
Вскрываем корпус модема.

image

На лицевой стороне расположены: модуль для карты памяти, контакты для SIM-карты, радио модуль под крышечкой, разъём, внутренняя антенна и USB-выход.

image

Интересно, что этот разъём недоступен без разборки корпуса, то есть почти все обладатели этого модема об этом разъёме даже не подозревают. Пусть он остаётся на месте, он нам не нужен и нисколько не мешает. А мешает нам внутренняя антенна:

image

Антенна вытравлена прямо на плате, и нам необходимо её отключить. Для этого сначала выкусываем SMD-конденсатор, предназначенный для резонансной согласовки антенны. Потом небольшой фрезой, зажатой в дрель, делаем пропил по антенне, оставляя только небольшую площадку для припайки кабеля. Разрез делаем неглубоко, так как печатная плата многослойная. Прозваниваем тестером, успешно ли прошла «ампутация» и нет ли КЗ между площадкой под припайку кабеля и отрезанной антенной. Кстати, иногда эта площадка может иметь КЗ на землю – таковы особенности архитектуры некоторых модемов. Если бы мы не отрезали внутреннюю антенну, то после подключения внешней антенны сигнал бы делился между ними, возникло бы рассогласование и ничего бы не получилось.

image

Припаиваем кабель к модему. Паяем быстро, точно и аккуратно, не перегреваем плату. Центральную жилу припаиваем на площадку, оставшуюся от внутренней антенны; оплётку припаиваем к любому месту, являющемуся землёй и расположенному как можно ближе к площадке с припаянной центральной жилой.

image

image

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

На этом все.


Источники:

  1. Антенна 3G своими руками для Huawei E1550 и других – 2100 mHz
  2. Ускорим 3G модем при помощи внешней антенны
  3. OpenVPN клиент на роутере TP-Link TL-MR3020 с OpenWRT
  4. Настраиваем OpenVPN сервер на подключения клиентов
  5. Openvpn-клиент на OpenWRT (tap)