Управление Synology Surveillance Station с помощью Telegram, Python и Docker

Общее представление о Synology

Synology является производителем сетевых систем хранения данных для организаций и домашних пользователей. Продукты от Synology это программно-аппаратные комплексы. В интернете много обзор на их устройства для домашнего применения. Часто их рекомендуют фотографам, видеомонтажёрам и всем остальным пользователям, которым требуется хранить данные и иметь к ним доступ в режиме 24 на 7.

Программно-аппаратные комплексы состоят из следующих элементов: сетевое хранилище, например такие модели, как: DS220+, DS720+, DS920+ и т.д. и программное обеспечение: операционная система DSM (на текущий момент версия 7.1) и различные модули, входящие в составе, например такие, как: Photos, Contacts, Download Station, Docker, Surveillance Station и другие. Часть из модулей имеет мобильные приложения и ими можно пользоваться с iOS или Android устройства.

Photos — модуль позволяет закачивать фотографии с телефона / планшета / компьютера, просматривать их, делиться ими с пользователями Synology и давать прямые ссылки в интернете при соответствующей настройке сетевого хранилища.

Contacts — приложение позволяет хранить контакты с разных устройств. На iOS синхронизация контактов происходит через встроенные инструменты мобильной ОС. На Android для синхронизации контактов потребуется платное приложение DAVx5.

Download Station — программа создана для скачивания торрентов.

Docker — согласно базы знаний Synology является виртуализированной средой для создания и запуска приложений в изолированном контейнере.

Surveillance Station (далее — Станция видеонаблюдения) — модуль позволяет настроить видеонаблюдение через различные камеры. На официальном сайте приводится полный перечень поддерживаемых камер видеонаблюдения. К примеру, в комплекте с DS920+ идет лицензия на подключение двух камер, если необходимо подключить больше двух, то следует докупать лицензии на каждую дополнительную камеру. Управлять Станцией возможно тремя способами: через приложение для ПК и Mac, через браузер и через мобильное приложение DSCam. В приложении для ПК имеется возможность настройки записи видеокамеры по расписанию. Например, возможно настроить срабатывание записи на движение в режиме 24 часа 7 дней в неделю на обнаружение движения.

813215b5b564829f9cd9cdc3f1e15654.png

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

В приложении для ПК и DSCam имеется возможно включения и выключения режима Home mode. Например, через включение режима происходит отключение расписание записи на обнаружение движения и прекращение получения уведомлений в мобильном приложении. Тем самым через режим Home mode включается и выключается режим охраны на Станции видеонаблюдения.

4cf386f27171f475c03398e31ea3adcd.png

Решение задачи по управлению Станцией видеонаблюдения, находящейся внутри локальной сети без доступа к интернет, через Telegram

Однако применение мобильного приложения усложняется при расположении Сетевого хранилища внутри домашней сети без прямого доступа в Интернет. При этом условии для включения/выключения режима Home mode необходимо подключаться к домашней сети через VPN, что усложняет управление Станцией видеонаблюдения. Также для просмотра видеопотока с камеры видеонаблюдения при срабатывании датчика движения необходимо вначале подключиться к VPN-сети, а после открыть DSCam для просмотра видеопотока в режиме реального времени.

Для управления Станцией без подключения к VPN-сети возможно с помощью применения языка Python, Telegram-бота, Docker и WebAPI Станции. Это позволит узнавать текущее состояние режима охраны, включать и выключать его через Home mode. Получать фотографии от камеры видеонаблюдения по запросу из Telegram.

В статье не будет освещен процесс создания Telegram-бота, через Bot_Father, так как данной информации много на просторах Сети.

Согласно документации к WebAPI Станции существуют основные параметры запросов «api»,»_sid», «method», «version» все остальные параметры являются уточняющими к каждому виду запроса.

Авторизация для разных целей происходит по разным портам. Для переключения режима Home mode авторизация осуществляется по адресу Станции видеонаблюдения http://192.168.1.3:9900/webapi/auth.cgi. Примером запроса на авторизацию в станции видеонаблюдения может быть:

requests.get( 'http://192.168.1.3:9900/webapi/auth.cgi', 
             params={'api': 'SYNO.API.Auth', 'method': 'login', 
                     'version': '7', 'account': 'Test', 
                     'passwd': 'RL2wXbx9', 'session': 'SurveillanceStation', 
                     'format': 'cookie12'})

Ответ будет следующим:

{'data': {'account': 'Test', 
          'device_id': 'qLDB5jfX7sxfdqws5MzCABW52jFKpxXiAbFE7QVzrdECrIvPDqR412355', 
          'ik_message': '', 'is_portal_port': False, 
          'sid': 'YxJx0PM0BGVlSgbgOfaN1zxmgXmxDaTD6WE1PYl47qohuGFobsLl7Eh0Y_s6MGBfW12356', 
          'synotoken': '--------'}, 'success': True}

Для авторизации последующих запросов необходима информация из поля «sid» через метод json ()['data']['sid']

Для получения фотографии от камеры видеонаблюдения авторизация происходит по адресу Сетевого хранилища http://192.168.1.3:5000/webapi/entry.cgi с передачей основных и вспомогательных параметров аналогично Станции видеонаблюдения. Для создания фотографии следует определить ID камеры видеонаблюдения для этого следует воспользоваться методом List, через следующий запрос

requests.get('http://192.168.1.3:5000/webapi/entry.cgi', 
             params={'api': 'SYNO.SurveillanceStation.Camera', 
                     '_sid': 'ответ поля sid в запросе на авторизацию', 
                     'version': '9', 'method': 'List' })

В ответе будет указан в том числе id всех камер видеонаблюдения с привязкой к IP адресам. В данном примере используется только одна камера с ip-адресом 192.168.5.120, id 7.

{'data': {'cameras': [{'DINum': 0, 'DONum': 0, 'audioCodec': 0, 
                       'channel': '1', 'connectionOverSSL': False, 
                       'dsId': 0, 'enableLowProfile': True, 
                       'enableRecordingKeepDays': True, 
                       'enableRecordingKeepSize': False, 
                       'enableSRTP': False, 'fov': '', 
                       'highProfileStreamNo': 1, 
                       'id': 7, 
                       'idOnRecServer': 0, 
                       'ip': '192.168.5.120', 
                       'lowProfileStreamNo': 1, 'mediumProfileStreamNo': 1, 
                       'model': 'Generic_HIKVISION', 'newName': 'Camera_1', 
                       'port': 80, 'postRecordTime': 5, 'preRecordTime': 5, 
                       'recordTime': 30, 'recordingKeepDays': 30, 
                       'recordingKeepSize': '10', 'status': 1, 
                       'stream1': {'bitrateCtrl': 2, 
                                   'constantBitrate': '3000', 'fps': 25, 'quality': '5', 'resolution': '2688x1520'}, 
                       'tvStandard': 0, 'vendor': 'HIKVISION', 'videoCodec': 6, 'videoMode': ''}]}, 
 'success': True}

Приведем код конфигурационного файла и файла Telegram-бота.

Код конфигурационного файла conf.py

user_id = [1234567, 2134567, 31234567]
token = 'Токен бота'

Код файла Telegram-бота bot_2.py

import conf
import telebot
import requests
import time
import os

token = conf.token
bot = telebot.TeleBot(token)

def auth(chatid):
    for i in conf.user_id:
        if i == chatid:
            return True
    return False


def get_snapshot():
    take_snapshot = requests.get(
        'http://192.168.1.3:5000/webapi/entry.cgi',
        params={'api': 'SYNO.SurveillanceStation.SnapShot', '_sid': auth_syn,
                'version': '1', 'method': 'TakeSnapshot', 'camId': '7',
                'dsId': '0', 'blSave': 'true'
                })
    time.sleep(1)
    return (url_photo + '/' + sorted(os.listdir(url_photo))[-1])

auth_syn = requests.get(
    'http://192.168.1.3:5000/webapi/entry.cgi',
    params={'api': 'SYNO.API.Auth',
            'version': '7', 'method': 'login', 'account': 'test', 'passwd': 'RL2wXbx9'
            }).json()['data']['sid']
auth_surv = requests.get(
    'http://192.168.1.3:9900/webapi/auth.cgi',
    params={'api': 'SYNO.API.Auth',
            'method': 'login', 'version': '7', 'account': 'Test', 'passwd': 'RL2wXbx9',
            'session': 'SurveillanceStation', 'format': 'cookie12'
            }).json()['data']['sid']

url_surv = "http://192.168.1.3:9900/webapi/entry.cgi"

url_photo = '/camera'
mes_start = ('Основные команды: \n'
             '/sec - состояние охраны \n'
             '/sec_on - включить охрану \n'
             '/sec_off - выключить охрану \n'
             '/photo - сделать фото')

@bot.message_handler(commands=['start'])
def start(message):
    if auth(message.chat.id):
        bot.send_message(message.chat.id, mes_start)


@bot.message_handler(commands=['sec'])
def sec(message):
    if auth(message.chat.id):
        home_mode_info = requests.get(url_surv,
                                      params={'_sid': auth_surv, 'api': 'SYNO.SurveillanceStation.HomeMode',
                                              'version': '1', 'method': 'GetInfo'}).json()['data']['on']
        if home_mode_info:
            bot.send_message(message.chat.id, "Охрана выключена")
        else:
            bot.send_message(message.chat.id, "Охрана включена")


@bot.message_handler(commands=['sec_on'])
def sec_on(message):
    if auth(message.chat.id):
        home_mode_off = requests.get(url_surv,
                                     params={'_sid': auth_surv, 'api': 'SYNO.SurveillanceStation.HomeMode',
                                             'version': '1', 'method': 'Switch', 'on': 'false'}).json()['success']
        if home_mode_off:
            bot.send_message(message.chat.id, "Охрана гаража включена")
        else:
            bot.send_message(message.chat.id, "Ошибка постановки в охрану")


@bot.message_handler(commands=['sec_off'])
def sec_on(message):
    if auth(message.chat.id):
        home_mode_on = requests.get(url_surv,
                                    params={'_sid': auth_surv, 'api': 'SYNO.SurveillanceStation.HomeMode',
                                            'version': '1', 'method': 'Switch', 'on': 'true'}).json()['success']
        if home_mode_on:
            bot.send_message(message.chat.id, "Охрана гаража выключена")
        else:
            bot.send_message(message.chat.id, "Ошибка снятия гаража с охраны")


@bot.message_handler(commands=['photo'])
def photo(message):
    if auth(message.chat.id):
        bot.send_photo(message.chat.id, photo=open(get_snapshot(), 'rb'))


@bot.message_handler(content_types=['text'])
def other_mes(message):
    if auth(message.chat.id):
        bot.send_message(message.chat.id, mes_start)


bot.infinity_polling()

 Коротко рассмотрим основные элементы кода.

В отдельном файле conf.py перечислим id пользователей Telegram, которые смогут управлять режимом охраны, а также пропишем токен бота.

В функции def auth (chatid): происходит идентификации пользователя, от которого получено сообщение.

В функции def get_snapshot (): происходит создание фотографии от камеры видеонаблюдения, результатом работы функции является путь на Сетевом хранилище до последней фотографии, которая позже будет отправлена в телеграмм.

В переменных auth_syn и auth_surv осуществляется авторизация на Сетевом хранилище и Станции видеонаблюдения.

В переменной home_mode_info определяется текущее состояние режима Home mode. Если Home mode включен, то телеграмм бот пришлет ответ, что охрана выключена, если Home Mode выключен, то охрана включена.

В переменных home_mode_off и home_mode_on представлено выключение и включение режима Home mode и соответственно режима охраны.

Запуск Telegram-бота в Docker

Рассмотрим каким образом осуществляется запуск телеграмм-бота в Docker на Сетевом хранилище Synology.

  1. Необходимо установить Docker, как стандартное ПО

  2. В разделе реестр скачать контейнер python.

082ffdcbb3e42bf503cd86d8da86af46.png

  1. В разделе образ начать процесс по созданию контейнера (далее — Контейнер), в нашем примере он будет называться bot_synology.

1d9161d22929e22bf49c2dd69f5420ec.png993b9eb6f4497c070088dbaf423a80cb.png

  1. В разделе дополнительные настройки и в подразделе том указать пути до следующих папок:
    1) папка с файлами телеграмм бота. Путь на Сетевом хранилище »/homes/Test/bot_synology» для контейнера будет соответствовать »/bot».
    2) папка с файлами фотографий с камеры. Путь на Сетевом хранилище »/surveillance/@Snapshot» для Контейнера будет соответствовать »/camera».

В разделе сеть оставить настройки по умолчанию (скриншот 7)

4b568c0dfd75d713fe5740c2280c4138.png

  1. Далее создать и запустить Контейнер.

После создания Контейнера необходимо скопировать файлы бота по ранее указанному адресу:»/homes/Test/bot_synology» любым удобным способом, например, по протоколу SMB.

Откроем сведения о Контейнере и перейдем в раздел Терминал.

В разделе терминал создадим еще один терминал, который автоматически будет назван bash. Через команду Переименовать переименуем Терминал bash в bot_syn. В котором можно будет вводить команды.

5e3248d9e11f57a66fe7e4811dcefbed.png878142d0764895052aac957ba74f84f2.png

Установим модуль pyTelegramBotAPI в Контейнере через команду «pip install pyTelergamBotAPI». Об успешном выполнении команды будет выведена информация, представленная на скриншоте ниже.

59b9121be4e9dce037775896979ede7e.png

Осуществим запуск телеграмм-бота, через панель управления Контейнером. Зайдем в раздел Терминал и с помощью команды ls увидим папки, в том числе добавленные ранее папки bot и camera.

С помощью команды «cd /bot» перейдем в папку.

Просмотрим имеющиеся файлы в паке bot через команду ls. В папке находится два файла bot_2.py и conf.py, которые мы создали ранее.

Через команду «python3 bot_2.py» осуществим запуск телеграмм-бота.

954436e8c44e6198a3a6ab253a3a3d42.png

Рассмотрим работу бота.

Отправим команду /start

Получим ответ с основным командами бота

Команда /sec — отображает текущее состояние охраны
Команда /sec_on — включает режим охраны
Команда /sec_off — выключает режим охраны
Команда /photo — делает фотографию с камеры и присылает в чат с ботом для оперативного просмотра информации от камеры.

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

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

Список использованных источников

  1. Инструкция по WebAPI Synology Surveillance

  2. Статья Python + Telegram

© Habrahabr.ru