В данной статье мы рассмотрим основные принципы работы telegram-бота для видеонаблюдения.
Прочитав статью о созданном телеграм-боте из подручных материалов, захотелось поделиться с общественностью своим решением для видеонаблюдения.
Железо
В отличие от подхода автора указанной статьи, я целенаправленно закупал необходимое оборудование для организации видеонаблюдения в квартире с целью дополнительной безопасности. Я купил IP-камеру которая умела следить за движением в кадре, складывать в папку на ftp и даже отправлять на email. Но всё это было, во-первых, неудобно, во-вторых, в прошивке была ошибка, что отправка на e-mail не работала должным образом, ну и, наконец, было много ложных срабатываний. Поэтому, решено было написать telegram-бота, как самый удобный способ для оповещения и управления наблюдением.
Итак, из железа у меня — камера фирмы IPEYE, которая умеет брать питания через сеть (POE), POЕ-инжектор, небольшой сервачок на Ubuntu Server, интернет с резервированием через USB-модем, ну и UPS для поддержки питания всей системы.
Определяем открытие двери
У меня всего одна камера, направленная на входную дверь. В идеале, мне хотелось, чтобы я получал изображение входящего в эту дверь человека. Сначала я пробовал настроить детекцию движения силами самой камеры:
Но к сожалению, как я ни крутил ползунки, камера в полумраке сходила с ума и начинала постоянно оповещать о движении в кадре при переходе из дневного в ночной режим и наоборот. Можно было, конечно, поднять motion
, он следит за движением в кадре гораздо аккуратнее. Но мне не хотелось поднимать дополнительный сервис, поэтому я решил оставить стандартную возможность камеры складывать изображения на ftp, и проверять на ложность срабатывания уже своими силами.
Для этого я написал простенький демон на php, который следит за папкой на предмет появления новых изображений, открывает их и анализирует разницу в освещённости заранее выбранных областей, примерно так (области специально выбраны выше, чтобы человек случайно не закрывал области):
Если разница превышает экспериментально подобранный порог, значит дверь действительно открыта.
Настраиваем бота
Итак, наш демон определил, что движение в кадре есть и дверь открыта. Дальше надо отправить это изображение в чат telegram. Для этого нам надо зарегистрировать нового бота через BotFather и получить API-ключ. Для взаимодействия с API Telegram я использовал библиотеку longman/telegram-bot. Телеграм предоставляет два способа получения новых сообщений long-polling и веб-хук. Второй способ мне показался предпочтительнее, но для его работы потребуется статичный URL с SSL-сертификатом. Для этого используем letsencrypt или самоподписанный сертификат который надо отправить BotFather. Подробнее о регистрации ботов можно почитать в документации телеграма.
Анализ wi-fi клиентов
Когда получаешь много сообщений, начинаешь их просто игнорировать, поэтому необходима была некая автоматизация, чтобы оповещения отправлялись только тогда, когда никого нет дома. Сделать это можно очень просто, достаточно просканировать сеть на наличие в ней определённых wi-fi клиентов. Для этого надо установить arp-scan
(sudo apt-get install arp-scan
), тогда определить что клиент с необходимым мак-адресом подключён можно так:
$output = exec("arp-scan -q --retry=1 --timeout=500 --numeric --destaddr={$mac} {$ip} | grep -oP --color=never "{$mac}"");
$result = $output === $mac;
Здесь я специально указываю конкретный ip-адрес, чтобы не сканировать всю сеть. Но для этого надо зафиксировать в DHCP ip-шник для этого MAC-адреса. Но, в принципе, указывать ip необязательно.
Запись видео
Фотографии это, конечно, хорошо. Но лучше всего покажет входящего человека — видео. Т. к. видео у нас никуда не пишется, "раздобыть" его можно только записав поток. К счаcтью, моя камера предоставляет несколько rtsp потоков закодированных в h264. Чтобы отправить видео, надо записать поток, и отправить его как файл. Для этого воспользуемся avconv
(форк ffmpeg
в Ubuntu):
$ffmpeg = "avconv -rtsp_transport tcp -i rtsp://user:password@192.168.1.10/1/h264major -t 10 -an -vcodec copy {$file}";
$mv = "mv {$file} {$out}";
passthru("nohup sh -c '{$ffmpeg} && {$mv}' > /dev/null 2>&1 &");
Здесь я пишу видео в фоне, после чего перемещаю его в папку для слежения. Демон подхватит новый файл и отправит его как видео. Т. к. звука в видео у меня нет, Telegram автоматически конвертирует его в gif на desktop-клиенте, что очень удобно.
Автоподнятие демона
Демон написан на php, и хотя он может работать месяцами, от ошибок никто не застрахован. Поэтому, хорошо бы следить, что демон не завершил процесс. Можно, было бы, конечно, настроить supervisor
, но я решил сделать просто автоподнятие по cron-у. Если процесс жив, демон повторно не запускается:
passthru("ps -p $pid > /dev/null", $result);
return !$result;
Заключение
Благодаря всем проделанным действиям, бот оповещает меня о входящем человеке двумя фотографиями и пятисекундным видео. Как бонус, бот также может оповещать о времени ухода и прихода определённых wi-fi клиентов, и находятся ли они сейчас дома.
С результатом вы можете ознакомиться на github.
Автор: PaulZi