Доработка модуля шлагбаума Doorhan GSM для управления через интернет +27




Недавно было решено установить в многоквартирном доме шлагбаум с управлением через GSM. Причины и необходимость этого решения остаются за рамками статьи, я же хочу написать про то, как «на коленке» сделал интерфейс для управления модулем через Интернет. И даже немного с блэкджеком, управлением базой автомобилей с мобильного телефона и фотографиями моментов въезда с уличной камеры. Возможно кто-то захочет внедрить у себя.

Предупрежу, что в статье не описано готовое решение «из коробки», а скорее proof of concept.

Часть 1. Почему такой контроллер


Перед тем, как ставить GSM-модуль был проведен некоторый обзор рынка таких систем. Хотелось получить недорогое, надежное и отработанное решение. Ну и чтобы «в наличии» было у установщиков, имелся какой-то опыт работы с ним и т.д.

Установщики на выбор предлагали либо ESIM 110/120 за ~12000р с доступом в интернет, либо Doorhan GSM за ~6000р с управлением через SMS или настройкой через USB-шнурок.

Вариант «сделать свой девайс из arduino + gsm модуль за $3» не рассматривался, так решение должно быть точно надежным и обкатанным. Представьте, кто-то не смог заехать домой? Потом неприятностей получишь по полной.

Так же не хотелось лотереи с покупкой устройства в Китае на Али, опять же во избежание проблем с надежностью. Хотя цены начинаются от 1500р.

Минусом ESIM120, кроме стоимости х2 было то, что для выхода в интернет использовался GPRS-интернет. Для кого-то может это и плюс, но в нашем случае тянет за собой расходы на мобильную связь — придется брать тариф с интернетом. Сейчас же на сим-карте подключен тариф без абонентской платы, и для того, чтобы номер не заблокировался, раз в 2-3 месяца планирую подключать из личного кабинета оператора какую нибудь платную подписку за 2-3 рубля в сутки, на одни сутки. Например «погоду», «анекдоты» или что там еще полезно для шлагбаума )

Про Doorhan GSM я знал, что помимо управления через SMS (мало интересно) он подключается по USB к компьютеру и через собственное ПО позволяет управлять базой номеров.

Часть 2. Проброс управления


Так как блок управления шлагбаумом планировалось ставить в 20 метрах от помещения, где расположен домовой IP-видеорегистратор и узел связи местного интернет-провайдера, то было решено взять Doorhan и «нарастить» USB через роутер вроде TP-Link MR3020 стоимостью 1200р, OpenWRT и программ из проекта USBIP

С роутером получилось даже несколько проще — нашел в закромах старый ASUS WL500gP, который для интернета не очень годится по нынешним меркам, зато имеет 2 USB порта. Его и использовал.

Для usbip пришлось поставить старую версию OpenWRT, 12.09, потому как на новых не работает этот модуль ядра. Подключение роутера к сети описывать не буду. Если у кого-то он будет не в локальной сети, возможны варианты с пробросом портов, UPNP или настройкой VPN, на ваш вкус.

Устанавливаем kmod-usbip-server и проверяем, что у нас можно экспортировать

root@OpenWrt:~# opkg install kmod-usbip-server
root@OpenWrt:~# usbip list -l
Local USB devices
=================
 - busid 1-1 (0424:2502)
         1-1:1.0 -> hub

 - busid 1-1.1 (1a86:7523)
         1-1.1:1.0 -> ch341

Нам нужен busid устройства, 1-1.1 на котором располагается наш подключенный контроллер GSM. Забегая вперед, оказалось что это банальный COM->USB конвертер на чипе CH341

Выполняем:

root@OpenWrt:~#usbipd -D
root@OpenWrt:~#usbip bind -b 1-1.1
bind device on busid 1-1.1: complete

и в dmesg

 usbip-host 1-1.1:1.0: usbip-host: register new device (bus 1 dev 57 ifn 0)

На компьютере с Windows устанавливаем драйвера USBIP и запускаем

usbip -a 10.16.19.19 1-1.1

где 10.16.19.19 IP-адрес нашего роутера с OpenWRT. Разумеется, для начала нужно отрыть доступ либо с вашего IP к роутеру в firewall, либо подключаться с локальной сети, либо любой из 1000 других вариантов от VPN до P2P.

Если все прошло успешно, то Windows радостно заявляет, что обнаружено новое устройство USB-to-Serial Converter CH340, даем ей драйвера и в системе появляется COM-порт.

Теперь можем запустить программку из комплекта с контроллером и управлять номерами в базе сидя дома на диване



Часть 3. Контроль въездов


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

Оказывается, GSM-модуль контроллера периодически шлет AT команды с уровнем сигнала в консоль, а так же при звонке пишет номер телефона, с которого поступает звонок. Управлять модулем AT командами не получилось, видимо они не транслируются от модуля контроллера в модуль модема.



Все равно это довольно интересно. При проработке идеи GSM-контроллером я надеялся, что эти звонки будут фиксироваться в детализации оператора. Но так как соединения не происходит, то записей в детализации нет. Теперь же можно прямо с контроллера собирать логи того, кто открывал шлагбаум. Или кто пытался это сделать.

Для этого на OpenWRT устанавливаем kmod-usb-serial-ch341, отключаем трансляцию USBIP командой usbip unbind -b 1-1.1 и делаем insmod ch341.

После чего прямо на роутере можно подключиться к /dev/ttyUSB0 и смотреть что там происходит со звонками в контроллере.

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

#!/bin/sh
cat /dev/ttyUSB0 | while read DATA; do
 if echo $DATA | grep -q CLIP ; then
  curl --silent --output /dev/null --data "data=$DATA" http://1.2.3.4:8081/border.php
 fi
done

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

Вторая идея, которая пришла мне в голову — сделать связку между событием открывания шлагбаума и фото этого события. Дело в том, как я упоминал выше, вокруг дома стоят AHD камеры, которые пишут на регистратор с доступом к потоку по IP. Причем одну из камер специально повернули на шлагбаум, в ожидании что его будут ломать.

Как снять jpeg с нашего китайского регистратора мне найти не удалось, хотя во многих камерах есть Preview URL. Поэтому пошел в лоб — в момент звонка получаю RTSP и делаю из него JPG.

ffmpeg -i "rtsp://2.3.4.5:554/user=user&password=password&channel=1&stream=0.sdp?" -y -f image2 -t 0.001 -ss 00:00:3 -s 1280*720 /tmp/screenshot.jpg

С таким же успехом можно было писать маленькие ролики в mp4, но я посчитал это лишним.
Фотографии решил хранить блобами в MySQL. Решение по производительности так себе, зато «таскать» проектик будет проще, не нужно копировать и базу и файлы, все в базе. А нагрузка на него никакая по сути.

В результате лог въездов выглядит как-то так:



Часть 4. Загрузка номеров из SQL базы на сайте в контроллер


Если вы внимательно читали, то наверное заметили — для регистрации въездов USB порт роутера работал в режиме Serial-to-USB преобразователя, а для работы с базой номеров внутри контроллера приходилось «прокидывать» его через USBIP на домашний компьютер и там через программу для Windows вносить изменения. Это не совсем удобно, нужно было делать unbind/bind да еще на домашнем компьютере запускать usbip консольный. Ну и делать это можно было только из дома (ну либо опять RDP/VPN и проч и проч), и тем более не с телефона мобильного. Вдвойне накаляло то, что базу номеров надо было вести и в mdb-формате (программа для контролера может выгружать данные в Access) и в веб-версии.

Беглый гуглеж протокола работы Doorhan GSM ничего не дал. Не исключаю, что это какая-то китайская девайсина под маркой Doorhan, тем не менее. Поэтому вооружился монитором (сниффером) для COM-порта и снял несколько дампов при работе из оригинального приложения.



Получил что-то вроде:
Команда на очистку памяти aa 02 09 00 00 03 e8 01 00 00 00 00 ee
Ответ что все прошло хорошо aa 20 00 ee
Команда на запись одного номера +79999999999
aa 03 10 00 01 2b 37 39 39 39 39 39 39 39 39 39 39 00 00 ee

Из чего сделал такие выводы:
начало посылки АА, конец посылки ЕЕ
Ответ, что команда принята 20 00
Команда на начало записи номера 03. Потом идет количество номеров в посылке. Может быть от 1 до 5, то есть за одну посылку можно отправить сразу несколько номеров подряд, закончив посылку командой ЕЕ, и получить одно подтверждение на блок.

После команды начала записи идет 2 байта (второй точно, первый возможно будет использоваться при количестве номеров больше 256 но не проверял), указывающие порядковый номер записи в ячейке. То есть если писать в пустую память, то сначала это 1, потом 2 и так далее. После чего идет 14 байт номера телефона. Так как наши номера«входят» в 12 байт (+79999999999) то последние 2 байта заняты нулями. Вероятно для всяких международных форматов типа +10. Это не точно, сильно не вникал, потому что хватило этих данных.

Завершается посылка байтом ЕЕ.

С порядковым номером ячейки не совсем понятная ситуация. Допустим, в контроллер записано 10 номеров, память не очищали. Если отправить команду «записать номер в ячейку 5», то номер в этой ячейке после контрольной вычитки не изменится, но в контроллере будет записано 11 номеров, причем 11-й будет пустой. А если дать команду «записать номер в ячейку 11», то он запишется в нее. Вероятно это связано с командами ADD и REPLACE (добавить и изменить), которые можно слать через SMS. Но так как оригинальное приложение делает только полное стирание и последующую перезапись списка, проверить гипотезу не получается. Поэтому свой вариант делал тоже отправкой команды стирания и последовательной записи по одному номеру (для простоты).

Итак, мы подошли к тому, чтобы писать в контроллер через последовательный порт команды на управление списком абонентов. Но порт в роутере, а база с пользователями на внешнем сервере. Переносить ее на роутер конечно можно (получится законченное решение «из коробки») но мне было лень. Пошел другим путем — прокинул /dev/ttyUSB0 по tcp с помощью пакета ser2net, который есть в поставке openwrt.

Конфиг /etc/ser2net.conf простой для неприличия

3333:raw:0:/dev/ttyUSB0:9600,remctl

После запуска ser2net можно подключиться к роутеру telnet-ом на 3333 порт и проверить результат.

Хочется сделать оговорку: после перезапуска роутера внезапно не работал cat /dev/ttyUSB0. То есть конечно работал, но в консоль писал мусор. Вспомнил, что во время экспериментов на роутере я запускал minicom, который вероятно сделал инициализацию порта. Просто установив режим 9600 8n1 результата не дало, поэтому я посмотрел с помощью stty какие настройки порта стоят в «рабочем» состоянии и вписал в rc.local инициализацию

stty -F /dev/ttyUSB0 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke

Наверняка что-то лишнее, читатели поправят возможно. Ну и если параметры порта указать в ser2net.conf то можно не ставить на роутер пакет stty.

В результате этих манипуляций на сервере с WEB-интерфейсом у нас стала доступна консоль контроллера. Поэтому немного перепишем код обработки звонков. Писал на PHP. Весь код стыдно показывать (я же не программист в конце концов, а использовал вставки из учебника), поэтому суть:

 $re = '/CLIP: ".(7\d{10})"/m'; //регэксп на входящий звонок
 while (1) {
   $f=@fsockopen('tcp://10.16.19.19',3333, $errno, $errstr); //подключимся к роутеру
   while ($f && $str=fread($f, 100)) {
     $test=preg_match($re, $str, $matches);
     if ($test)  process_call($matches[1]); //пришел звонок, запишем в базу и сделаем фото
//проверим нужно ли записать телефоны из базы в контроллер и сделаем это, если нужно, используя дескриптор $f
     sync_phones($f); 
   }
   if ($f) fclose($f); //что-то пошло не так
   sleep(5); //подождем 5 сек и сделаем реконнект
 }

process_call каждый думаю реализует как ему нравится, от записи информации в лог-файл, до создания фото/видео въезда и отправки их через Телеграм-бота на телефон супруга/супруги, а так же команды на кофеварку или для разогрева борща.

На sync_phones остановлюсь чуть подробнее, потому как там реализован тот самый «не публичный» алгоритм работы GSM-контроллера Doorhan. И да, рукалицо, я использовал mysql вместо pdo или mysqli.

function sync_phones($f) {
  /*
 В таблице config хранится переменная update. Если в веб-интерфейсе сделать val=1, то должен запуститься процесс обновления номеров в контроллере. Можно сделать семафор через файл,  но раз я все равно использую mysql, то решил сделать так
 */ 
  $result=mysql_query("SELECT * FROM config WHERE name='update' AND val=1");
  if (mysql_num_rows($result)==0) return; 
  
  $init =  pack('H*','aa1100ee'); //какой-то пакет инициализации при подключении программы к контроллеру
  $clear = pack('H*','aa0209000003e80100000000ee'); //команда на стирание данных (выдрано с дампа СОМ-порта)

  $logfile=fopen("/tmp/border.log","a");
  fwrite($logfile,"Update started at ".date('Y-m-d H:i:s')."\n");

  fwrite($f,$init);
  sleep(1);
  $ans=fread($f, 40);
  fwrite($logfile,"Send init. Answer ".bin2hex ( $ans )."\n");

  fwrite($f,$clear);
  sleep(1);
  $ans=fread($f, 40);
  fwrite($logfile,"Send clear. Answer ".bin2hex ( $ans )."\n");


  $result=mysql_query("SELECT * FROM phones ORDER BY pid");
  //тут все ясно, select всех номеров из базы пользователей, чтобы записать их в контроллер
  $n=1;
  while($row=mysql_fetch_array($result)) {

    $start = 'aa0310';
    $pos   = sprintf("%04x",$n);
    $phone = bin2hex('+'.$row['phone']).'0000';
    $end   = 'ee';

    //собираем "посылку"
    $send=$start.$pos.$phone.$end;
    $bin=pack('H*',$send);

    fwrite($f,$bin);
    $ans=fread($f, 40);
    fwrite($logfile,"Write {$n} phone {$row['phone']}. Answer ".bin2hex ( $ans )."\n");
    $n++;
  }
  fwrite($logfile,"End update\n");
  fclose($logfile);
  //запишем в наш "семафор" время, когда обновление завершено, полезная информация. И сам флажок, что обновление не требуется
  mysql_query("UPDATE config SET val=0,result='".bin2hex ( $ans )."',updated=NOW() WHERE name='update'");
}
?>

Часть 5. Заключение


В результате я получил (написал) WEB-интерфейс для шлагбаума, куда могу заходить через мобильный браузер, добавлять/удалять/изменять там номера жильцов нашего дома, делать пометки, с привязкой к квартире, ФИО, номеру телефона, номеру авто. Есть фотографии авто, лог въездов через шлагбаум с фото. В будущем, по логам посмотрю кто создает наибольшую нагрузку на шлагбаум — тот и будет оплачивать ремонт :)

Ну и бонусом получил WIFI-точку на парковке возле дома.

Цена вопроса — 0 рублей и выходной за компом.

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (22):

  1. NordicEnergy
    /#18834547

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

    • trublast
      /#18834559

      В дачных обществах часто используют GSM-контроллеры, но мой вариант управления вряд ли подойдет — проводного интернета там обычно нет.
      Поэтому либо контроллер вроде Дорхановского с управлением базой СМС-ками с привязанного телефона по одному-пять штук за SMS. Либо ESIM120, там облачный сервис.

      Вообще GSM-контроллеры такого плана выгоднее, чем «классические» пульты. Один контроллер стоит ~6000р, один пульт ~600р. Если пользователей больше 10, то выбор очевиден.

      • trublast
        /#18834565

        Возможно конечно во второй USB-порт роутера вставить GSM-модем (либо через USB-хаб, если нет второго порта), но это нужно еще модем за 500-1000р и вторую СИМ-карту с тарифом на интернет. По цене выходит дешевле ESIM120, но это пляски с бубном, костыль на костыле. И вторая симка с абоненткой, чего и хотелось уйти.

      • NordicEnergy
        /#18834569

        Сейчас все СНТ в зоне «10 км от города» больше на коттеджные поселки похожи, к нам ростелеком давно оптику прокинул) С пультами уже была идея, приехали подрядчики и насчитали что-то совсем неадекватное по деньгам. Можно сделать на китайских пультах, но нормального мониторинга не будет, а он интересен наверное в первую очередь даже.

    • j_wayne
      /#18837205

      В ТСЖ GSM-модуль в конце-концов поменяли на ИК. Думаю, есть свои минусы, но в принципе, мне удобнее открывать пультом, чем в узком проездике (в одну машину шириной) второпях ковыряться в смартфоне (бабушкофон звонилка наверное был бы куда удобнее).

      • trublast
        /#18838663

        Мне удобнее открывать, нажав на иконку шлагбаума на магнитоле с андроид (номер магнитолки внесён в базу)
        В крайнем случае "окей Гугл позвонить 'открой ворота'"
        Ну или вариации на тему.


        Если хочется прям пульт, то берется старый ненужный бабушкофон, либо новый за 800р (цена сравнима с ценой пульта) и бросается в машину на постоянку.

        • j_wayne
          /#18838677

          С магнитолой интересно. Но не всем доступно из коробки (\me смотрит на свою унылую штатную CD MP3 магнитолу).
          Видимо еще и ТСЖ заколебалось списки вести.

          • trublast
            /#18838697

            Да бог с ней, с магнитолой.
            Практически на всех смартфонах сейчас можно вынести контакт на рабочий стол. Чтобы открыть ворота/шлагбаум достаточно разблокировать телефон и ткнуть в иконку.
            С разблокировкой тоже решаемо. На некоторых смартах появилась функция типа "не блокировать в зоне действия блютус", где предлагают выбрать доверенные устройства. Например, гарнитура или громкая связь в авто. Ну или в конце концов сейчас много где есть сенсор отпечатка.
            Остаётся только извлечь телефон из кармана.

  2. klirichek
    /#18834567

    С блэкджеком, говорите?
    А он потом не подпишется сам на рассылки куртизанок?
    (как, вон, у кого-то гаражные ворота)..

    • trublast
      /#18834591

      Ну на этот счет у меня все ходы записаны :-) Мониторинг баланса стоит
      А если серьезно, то как я написал в статье, управлять именно GSM-модулем внутри контроллера не удалось, то есть с него ни позвонить нельзя, ни смс отправить через СОМ-порт. Что, может быть, не совсем удобно, я бы воспользовался этими функциями в том числе.

    • xandr0s
      /#18835551

      Зубов бояться — в рот не давать Волков бояться — в лес не ходить. В интернете, говорят, можно наткнуться на цопэ и другие страшные вещи. Но почему-то от него никто не отказался

  3. baxtep2
    /#18834835

    Хабр торт. Посоветуйте самый дешевый gsm контроллер для личных ворот. И самый дешевый wifi(наверное это sonoff).

  4. EgorZanuda
    /#18835529

    1. Если кому приспичить сломать Вам шлагбаум камеры вам не помогут.
    2. Теперь самое интересное, расскажите как вы храните персональные данные. Поверьте в ваших же интересах не хранить и не собирать ту информацию которая вам не нужна.

    • trublast
      /#18835545

      1. Тем не менее уже помогли, и уже восстановили сломанный ИК-датчик за счет вандалов.
      2. Ой, да разве это я храню? Данные прислали мне собственники на почту в Яндексе, вместе с заявлениями на регистрацию их номера для открытия шлагбаума. Мой скрипт конечно же ходит по IMAP в Яндекс и берет информацию оттуда.

  5. Newm
    /#18835557

    Ой, рисковые какие ребята. При обработке персональных данных надо всегда помнить о роскомнадзоре:(. Я почти уверен, что не то, что куча бумаг политики по обработке не написана, но даже элементарные согласия на обработку персданных не собраны. В общем, рекомендую почитать закон 152-ФЗ и в случае любых претензий от любого ненормального жильца сразу все стирать и «я не я, корова не моя». И уж точно не пытаться кому-то что-то доказать с помощью фото с наблюдения, иначе можно огрести проблем на свою голову.

    • trublast
      /#18835569

      В целом вы правы. Хорошо, что номера телефонов хранятся в контроллере и SQL с айдишниками, а остальные данные на сертифицированных ФСТЭК серверах. То есть в письмах на Яндексе, куда люди присылали свои данные на включение в список шлагбаума. Может это не так, но нужно провести аудит кода.
      Закон может и правильный, но какой-то оторванный от реальности. И, честно говоря, какой-то сложный для понимания.
      Я вот задумался, я храню у себя в смартфоне номера телефонов людей, и там так же записаны ФИО, а бывает адрес и/или марка авто. Часто — место работы. Ну и фотка тоже бывает.
      Например: +79998881122 Семенов Александр Сергеевич, Ленина 1, зеленая мазда с443мм777
      Так вот, является ли это хранением ПД, а поиск по записной книжке — обработкой ПД? А если я карточку кому-то перешлю — это пересылка? А создание бэкапа? А то, что гугл/аппл сливает всю телефонную книжку в облако (с согласия конечно, но у меня включено, ибо удобно) — как с этим быть?

      Все это подпадает под обработку персональных данных, и я, а вместе со мной еще 95% граждан РФ, должны заявиться как операторы ПД. Потому как не попадаем под исключения, когда заявление не требуется.

      • Newm
        /#18835641

        Обработка персональных данных для ЛИЧНЫХ и СЕМЕЙНЫХ целей не требует каких-либо действий от оператора персональных данных (в законе дано такое исключение). А вот пересылка карточки кому-то из знакомых, не являющихся членами семьи, — это уже полноценный оператор со всеми требованиями.

        Я к тому, что во дворе ночью стукнули машину машиной. Жертва идет к управляющему шлагбаумом и просит посмотреть всех, кто был во дворе. Управляющий по доброте душевной ЕСТЕСТВЕННО желает помочь жертве и дает нужную информацию. И сам влетает на административное правонарушение.

        • trublast
          /#18835663

          Да, видел это упоминание. Пока непонятно, какая цель в данном контексте является личной. Этот интерфейс я сделал лично для себя и доступ не предоставляю никому. Попадает под определение личной цели?

          По второму абзацу. Допустим, нет никакой системы с шлагбаумом, просто камера. Жертва идет к старшему по дому (в данном случае ко мне), и мы смотрим запись с регистратора. Находим там, кто стукнул машину. Ну и так как я знаю, допустим, чья она, то сообщаю потерпевшему «да это Нива Сереги с 3-го этажа». Система видеонаблюдения не хранит персональные данные, а результат не меняется.

          Можно даже упростить. Подходит ко мне сосед и спрашивает: «ты не знаешь, чья это нива стоит поперек двора, выехать не могу?» И если я отвечаю «да это Сереги с 3-го этажа», то выходит я совершаю административное правонарушение?

  6. Newm
    /#18836151

    По первому абзацу… До тех пор, пока данные никому не передаются, МОЖНО трактовать как цели личные. Но при возникновении конфликта без адвоката в суде самому могут быть сложности с таким трактованием.

    По второму… Если дать сведения напрямую жертве, то однозначно нарушение. Если же жертва идет в полицию и там сообщает, что есть камера от старшего по дому, а они уже спрашивают, то тут уже не совсем все ясно, но есть ВОЗМОЖНОСТЬ законной трактовки.

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

    • EgorZanuda
      /#18836761

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

      • trublast
        /#18838669

        Как раньше выживали бабушки на скамейках у подъезда — ума не приложу. Они про всех все знали, без "этих ваших кампутеров". Хотя им помогало отсутствие ФЗ о защите ПД вероятно.