Skip to content

Интеграция Flussonic Watcher с системами контроля и управления доступом

Flussonic Watcher умеет отправлять команды системам контроля доступа для открытия дверей после того, как Watcher распознал человека из списка. Ниже приведен скрипт для интеграции с системой контроля доступа Sigur и с комментариями по его использованию.


import socket
import sys
import argparse
import http.server
import socketserver
import cgi
import json
import requests
import logging
import logging.config
from logging.handlers import TimedRotatingFileHandler

fh = TimedRotatingFileHandler("ACS_integration.log", when='midnight')
sh = logging.StreamHandler()
logging.basicConfig(handlers=(fh, sh),  
                    format='[%(asctime)s.%(msecs)03d | %(levelname)s]: %(message)s', 
                    datefmt='%d.%m.%Y %H:%M:%S',
                    level=logging.INFO)

class ACS_Sigur:
    @staticmethod
    def connect(ip, port):
        sigur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sigur.connect((ip, int(port)))
        except:
            print("Connection error: ", sys.exc_info())
        else:
            print("Sigur server connected!")
        return sigur

    @staticmethod
    def login(sigur):
        message = "LOGIN 1.8 Administrator\r\n" #Change your credentials to connect to Sigur
        sigur.send(bytes(message, 'utf-8'))
        reply = sigur.recv(1024)
        data_reply = reply.decode('ascii')
        data_reply.replace('\n','')
        if "OK" in data_reply:
            print("Login in server successfull")
        else:
            print("Sigur server is not connected. That is why:", data_reply)

    @staticmethod
    def open_door(sigur):
        message = "ALLOWPASS 1 2 IN\r\n" #Change ID of a door you want to open. You can find ID in a Sigur app.
        sigur.send(bytes(message, 'utf-8'))
        reply = sigur.recv(1024)
        data_reply = reply.decode('ascii')
        data_reply.replace('\n','')
        if "OK" in data_reply:
            print("Door is opened")
        else:
            print("Something went wrong. That is why:", data_reply)

def create_cmd_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument('-ACS', action="store", dest="ACS")
    parser.add_argument('-ip', action="store", dest="ip")    
    parser.add_argument('-port', action="store", dest="port")
    parser.add_argument('-serverport', action="store", dest="serverport")

    return parser

parser = create_cmd_parser()
args = parser.parse_args()

class MyHandler(http.server.BaseHTTPRequestHandler):
    def do_POST(self):
        logging.info("New request from {client}".format(client = self.client_address))
        content_length = self.headers.get('content-length')
        if content_length == None:
            result = ""
        else:
            body = self.rfile.read(int(content_length))
            result = json.loads(body, encoding='utf-8')
        logging.info("Request JSON is: {result}".format(result = result))
        if args.ACS == "Sigur":
            logging.info("Trying connect to the Sigur server")
            try:
                sigur = ACS_Sigur.connect(args.ip, args.port) 
                logging.info("Sigur server connected")
                ACS_Sigur.login(sigur)
                logging.info("Success login on a Siger server")
                try:
                    ACS_Sigur.open_door(sigur)
                    logging.info("Success login on a Sigur server")
                except:
                    logging.warning("There was a problem while opening door")
                sigur.close()
                logging.info("Connection with the Sigur server closed")
            except:
                logging.warning("Something went wrong. Basic request is nor JSON: {body}".format(body = body))

        if args.ACS == "Beward":
            logging.info("Trying connect to the Beward")
            uri = 'http://'+args.ip+'/cgi-bin/io/port.cgi?action=O0:/'
            try:
                response = requests.get(uri, auth=('admin', 'admin'))
                if response.status_code == 200:
                    logging.info("Door was opened")
                else:
                    logging.warning("Something went wrong")
            except:
                logging.warning("There was an error while sending command to Beward")

def main():
    logging.info("Application started ACS - {ACS}, IP address - {ip}, port - {port}, serverport - {serverport}".format(ACS = args.ACS, ip = args.ip, port = args.port, serverport = args.serverport))
    if args.ACS == "Sigur":
        logging.info("ACS Sigur chosen")
    elif args.ACS == "Beward":
        logging.info("ACS Beward chosen")
    else:
        logging.info("ACS is unknown. Please use \"Sigur\" or \"Beward\".\nIntegrated module shutted down.")
        sys.exit()
    try:
        with socketserver.TCPServer(("127.0.0.1", int(args.serverport)), MyHandler) as httpd:
            logging.info("Started listening port {port}".format(port = args.serverport))
            httpd.serve_forever()
    except:
        logging.warning("Cannot connect to the listening port or someone shut application down")
        sys.exit()

if __name__ == "__main__":
    main()

Как использовать этот скрипт для интеграции Watcher co СКУД:

1) Измените список сценариев в соответствии с вашей установкой Sigur. Вам нужно будет установить логин и пароль к Sigur, отредактировав строку:

message = "LOGIN 1.8 Administrator\r\n"

2) Измените ID двери, которую необходимо открывать:

message = "ALLOWPASS 1 2 IN\r\n"

3) Отредактируйте файл systemd сервиса, чтобы добавить автозапуск:

[Unit]
Description=ACS Unlocker
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=3
User=root
Group=root
WorkingDirectory=/opt/acs-unlocker
ExecStart=/opt/flussonic/bin/python3 runner.py -ACS Sigur -ip {IP} -port 3312 -serverport {serverport}

[Install]
WantedBy=multi-user.target

Вам необходимо указать {IP} сервера Sigur и {serverport} на сервере с установленным модулем интеграции, который будет прослушивать события от модуля распознавания лиц Flussonic Watcher и отправлять их в Sigur.

Замечание: Порт {serverport} следует использовать при настройке подписки на уведомления о событиях в модуле распознавания лиц.

4) Перезагрузите и перезапустите новую службу systemd.

5) Подпишитесь на события распознавания лиц с помощью Flussonic Watcher API, который отправляет событие на порт сервера, который вы выбрали в файле .service. События распознавания лиц имеют тип person_detected, а если вы строите СКУД на распознавании номеров авто, то используйте тип car_detected.

Пример скрипта для создания подписки на уведомления о персоне с id=1:

curl --header "Content-Type: application/json" \
--request POST \
-d '{"camera_id": "person.detection.test.camera-7d8ea4ebf2",
"notification_type": "http",
"event_type": "person_detected",
"webhook_params": {
  "url": "http://example.com",
  "method": "post",
  "params": {
      "mode": "single",
      "id": 1
}}}' \
http://localhost/vsaas/api/v2/my/subscriptions

Обратите внимание, что параметр mode может принимать значения single (одна персона) и list (список персон), и в зависимости от этого id будет соответственно идентификатором конкретной персоны или списка персон.

В параметре url укажите адрес сервера, на который отправлять уведомления. Для notification_type на данный момент поддерживается только значение http.

6) Произведите распознавание и проверьте правильность работы модуля интеграции.