Открываем двери удаленно

в 14:04, , рубрики: processing, системное администрирование, метки:

image
У нас в офисе некоторые важные двери открываются «карточками» — бесконтактными RFID ключами. Называется все это дело СКД и построено на базе ПО Орион от Bolid. Однажды мне подумалось: «вот было бы здорово открывать двери со смартфона!». Challenge accepted!

Шаг 1.
Беглый осмотр «Оперативной задачи» и «Администратора базы данных» (компонентов ПО Орион) показал, что НЕчеловеческое вмешательство в работу системы не представляется возможным. По крайней мере в открытых источниках об этом ничего не говорится. Но есть возможность добавления «Сценариев управления».

image

Это дает нам возможность выполнять некоторую последовательность действий нажатием какой-либо клавиши (или их сочетание). Уже кое-что. Добавляем сценарий, назначаем его на клавиши (Shift+W в моем случае), проверяем (не забыв предварительно сделать «Обновление БД в Оперативной Задаче» в пункте меню Сервис) — работает!

Шаг 2.
Первый шаг нам не принес большой пользы. Открыть дверь можно только нажав нужное сочетание клавиш в «Оперативной задаче». Остается только идти в лоб: эмулировать нажатие кнопок. Так как программист из меня не очень, да и времени много тратить на это не хотелось, выбор средства реализации этого извращения пал на Processing. Пишем код:

import processing.net.*;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;

Robot robot;

String HTTP_GET_REQUEST = "GET /";
String HTTP_HEADER = "HTTP/1.0 200 OKrnContent-Type: text/htmlrnrn";

Server s;
Client c;
String input;
char keycode;

void setup() 
{

  s = new Server(this, 8080); // start server on http-alt
  try { 
    robot = new Robot();
  } 
  catch (AWTException e) {
    e.printStackTrace();
  }
}

void draw() 
{
  // Принимаем запрос от клиента
  c = s.available();
  if (c != null) {
    input = c.readString();
    input = input.substring(0, input.indexOf("n")); // одной строки будет достаточно
    
    if (input.indexOf(HTTP_GET_REQUEST) == 0) {
      c.write(HTTP_HEADER);  
    
      input = input.substring(4,7); // вырезаем только кусок запроса с параметром

      if(input.indexOf('q') > 0) keycode=KeyEvent.VK_Q;
      if(input.indexOf('w') > 0) keycode=KeyEvent.VK_W;
      if(input.indexOf('e') > 0) keycode=KeyEvent.VK_E;
    

      // жмем клавиши
      robot.keyPress(KeyEvent.VK_SHIFT);
      robot.keyPress(keycode);
      // отпускаем клавиши
      robot.keyRelease(keycode);
      robot.keyRelease(KeyEvent.VK_SHIFT);

      c.stop();       // закрываем соединение
    }
  }
}

Скажу честно: код взял из примеров. Думаю все поймут что там происходит.
Кто не понял — поясняю: слушаем порт 8080, получаем запрос, вытаскиваем из него нужный параметр, адекватно на него реагируем.
Получился такой мини-сервер на коленке. Нужно его запустить на сервере СКД и он сам будет делать что нужно.

Шаг 3.
Мы уже умеем не просто открывать дверь, но удаленно. Осталось написать вэб-морду.

<?PHP
header("Content-Type: text/html; charset=windows-1251");

$act = $_REQUEST['act'];
if(!$act) buttons();  // рисуем кнопки
if($act=='push') push();  // обрабатываем нажатия

function push(){
    $btn = $_REQUEST['btn']; 
    if($btn!='') { // проверяем наличие параметра
        $fp = fopen("http://адрес_нашего_сервера_СКД:8080/".$btn, "r");
        fclose($fp);
    }
}

function buttons() {  // просто выводим кнопки и обработчик нажатий на JavaScript
    ?>
    
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd"><html><head>
    
<script type="text/javascript">
function getXmlHttp(){
    var xmlhttp;
    try {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
        try {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (E) {
            xmlhttp = false;
        }
    }
    if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
        xmlhttp = new XMLHttpRequest();
    }
    return xmlhttp;
}


function btnClick(i) {
    //alert(i);
    var req = getXmlHttp();
    req.open('GET', 'index.php?act=push&btn='+i, true);
    req.send(null);
}
</script>

    <button style="width: 100%; height: 50px;" onclick='btnClick("q")'>Кухня</button><br><br>
    <button style="width: 100%; height: 50px;" onclick='btnClick("w")'>2 этаж</button><br><br>
    <button style="width: 100%; height: 50px;" onclick='btnClick("e")'>Менеджеры</button><br><br>
    
</head></html>
    <?PHP
}
?>

Именно ВЭБ исполнение выбрано для большей универсальности: можно запустить на любой платформе. Хотя можно написать на том же Процессинге и запускать на Android.

Резюме.
Безусловно, это костыль. Система имеет много критических недостатков. Двери открываются Администратором системы, а не сотрудником, что делает невозможным учет рабочего времени и отслеживание перемещения сотрудника по офису. Эмулятор нажатия клавиш не работает пока пользователь системы, под которым он запущен, не активен. Пользоваться им, конечно, можно, но это было сделано за час.
Если у вас есть предложения по улучшению этого проекта, буду рад услышать.

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

Автор: mehos

Источник

Поделиться

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