Настройка камеры в Telegram

Привет, меня зовут Иван. Сразу отвечу на главный вопрос: почему стал собирать сам, а не взял готовое решение? Во-первых, стоимость готовых решений — Raspberry Pi со всеми датчиками и камерой вышла не больше $30, большая часть еще по курсу 60 рублей за доллар. Во-вторых, почти все части уже были — Raspberry Pi отдал брат, камера осталась еще с лохматых времен, диод тоже был — покупал для Arduino, а датчик движения на Aliexpress стоил не больше 100 рублей.

Повествование в статье будет построено следующим образом:

  1. Определим что нам потребуется;
  2. Поработаем с диодом;
  3. С датчиком движения;
  4. С камерой (фото);
  5. С камерой (видео);
  6. Разберем работу с Telegram-ботом (рассмотрим скелет);
  7. Создадим «Умную камеру»;
  8. Посмотрим на работу «Умной камеры»;
  9. Определим узкие места и возможные решения.

Что нам потребуется

Эти настройки КАМЕРЫ iPhone тебя УДИВЯТ / Ты ДОЛЖЕН включить эти настройки КАМЕРЫ на iPhone

На Raspberry должен быть настроен интернет, установлены:

  • ffmpeg — для записи видео с камеры;
  • Python 3.7.

У Python должны быть следующие библиотеки:

  • RPi.GPIO;
  • pygame;
  • telebot.

И понадобятся провода — F2F, что бы все это соединить.

Работа с диодом

import RPi.GPIO as GPIO import time LED_PIN = 3 def setup(): GPIO.setmode(GPIO.BOARD) GPIO.setwarnings(False) GPIO.setup(LED_PIN, GPIO.OUT) def destroy(): GPIO.output(LED_PIN, GPIO.LOW) GPIO.cleanup() def blink(): GPIO.output(LED_PIN, GPIO.HIGH) time.sleep(1) GPIO.output(LED_PIN, GPIO.LOW) def main(): setup() blink() destroy() if __name__ == ‘__main__’: main()

Импортируем библиотеку для работы с нодами Raspberry, определяем нод для диода.

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

Работа с датчиком движения

Перед подключением датчика движения к Raspberry необходимо для начала определить какой провод за что отвечает, потому что на некоторых датчиках земля находится слева, на некоторых — справа и это будет кардинально влиять на работу датчика:

Как настроить камеру iPhone

После этого можно подключать датчик и настраивать его физически — скорректировать значение delay и sensitivity для своих нужд, вот пример моей настройки:

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

В принципе, работа с датчиком движения сводится к одному методу — методу чтения сигнала с датчика (16 строка).

import RPi.GPIO as GPIO import time PIR_PIN = 11 def setup(): GPIO.setmode(GPIO.BOARD) GPIO.setwarnings(False) GPIO.setup(PIR_PIN, GPIO.IN) def destroy(): GPIO.cleanup() def sensorJob(): while True: i = GPIO.input(PIR_PIN) print(«PIR value: » + str(i)) time.sleep(0.1) def main(): setup() sensorJob() destroy() if __name__ == ‘__main__’: main()

Определяем нод для датчика движения. В методе настройки библиотеки указываем, что по указанном ноду будет читаться сигнал. В главном методе — sensorJob в бесконечном цикле считываем сигнал, выводим значение в консоль и ожидаем небольшой промежуток времени.

Работа с камерой (фото)

С «железом» разобрались и теперь можно переходить к съемке фото и видео. Подключаем камеру к любому USB-порту, по необходимости, настраиваем. Вероятнее всего, операционная система сама подцепит нужные драйвера и дополнительной настройки не потребуется. Если у вас подключена 1 камера она будет называться /dev/video0. Также важно определить разрешение камеры, потому что можно получить фотографии сплошным черным цветом.

from datetime import datetime import pygame import pygame.camera pygame.init() pygame.camera.init() pygame.camera.list_cameras() cam = pygame.camera.Camera(«/dev/video0», (640,426)) def saveCapture(): filename = datetime.now().strftime(‘%d-%m-%Y %H:%M:%S’) + ‘.jpg’ cam.start() pygame.image.save(cam.get_image(), filename) cam.stop() def main(): setup() saveCapture() destroy() if __name__ == ‘__main__’: main()

Импортируем библиотеку для работы с камерой. Инициализируем библиотеку, инициализируем расширение для работы с камерой, выводим список доступных камер, сохраняем нужную нам камеру в переменную, во втором параметре указываем разрешение камеры. В методе saveCapture определяем название файла, вызываем метод start у камеры, через метод get_image() у камеры получаем объект со снимком, сохраняем его методом pygame.image.save, в завершение останавливаем работу камеры методом stop. Очень важно останавливать работу камеры через библиотеку pygame, потому что библиотека ffmpeg будет пытаться использовать камеру и в случае, если мы ее не освободим будет завершаться ошибкой.

Работа с камерой (видео)

Для съемки видео мы будем отправлять в терминал сообщение следующего вида:

ffmpeg -f v4l2 -framerate 25 -video_size 640×426 -i /dev/video0 -t 5 -c copy

Где будем указывать формат видео — v4l2, количетсво кадров, разрешение съемки, главный аргумент -c copy, если у вас медленная камера, с этим параметром съемка и сохранение файла будет происходить в десятки раз быстрее, но будет отсутствовать preview у видео и в Telegram не будет отображаться количество времени, которое длится видео. Также, нельзя будет просмотреть видео прямо из Telegram, потребуется отдельный плеер.

Каркас Telegram-бота

Перед рассмотрением работы с Telegram-ботом предполагаем, что вы уже получили ключ от BotFather и выполнили настройку бота на стороне Telegram, там нет ничего сложного, поэтому не будем на этом останавливаться. Также, мы будем работать сразу с InlineKeyboard у Telegram-бота, потому что это удобно и не нужно переживать о том, как правильно писать ту или иную команду. Кроме того, в самом начале будем делать проверку на ID пользователя, чтобы никто случайно (или специально) не подглядывал в нашу камеру.

Импортируем классы для InlineKeyboard, импортируем библиотеку Telegram-бота. В переменной TOKEN указываем ключ от BotFather. Сохраняем ADMIN ID. С помощью нотаций указываем команду для метода start. В методе start делаем проверку на USER ID и если это не мы, то выводим сообщение и выходим из метода, если же это мы, то отправляем InlineKeyboard с доступными командами.

При отправке клавиатуры можно также сразу отправлять и текст. В методах sendCapture и sendVideo показаны примеры команд для отправки фото и видео через Telegram-бота. Далее нам нужно указать метод, который будет обрабатывать нажатия на InlineKeyboard, тоже через нотацию, но теперь нотация немного другая, вызов метода по нажатию на кнопку делаем по имени этого метода.

В методе main вызываем bot.pooling, который в бесконечном цикле проверяет наличие входящих сообщений боту. Если у вас быстрая Raspberry и интернет, то можете не указывать параметры у этого метода и оставить их по-умолчанию. У меня стабильность отправки сообщений была низкой из-за чего пришлось добавить interval = 5. В конце статьи расскажу на что это влияет.

«Умная камера»

Подключаем диод и датчик движения к нужным GPIO нодам, камеру к USB.

У меня это выглядит вот так:

Теперь соберем все куски логики, описанные ранее и получим «Умную камеру» с управлением через Telegram-бота.

Работу сенсора будем запускать в отдельном потоке, поэтому импортируем необходимую библиотеку. Создаем переменную для хранения расширения видео. Логирование из библиотеки logging не влияет на работу «Умной камеры», поэтому не будем заострять на этом внимание. Создаем переменные для флагов о работе сенсора и необходимости отправки уведомлений.

Создаем переменную для хранения последнего chat_id, зачем это — расскажу позже. Переменная для хранения клавиатуры нужна, чтобы можно было повторно отправлять нужную клавиатуру. Дальше идет знакомый нам код по инициализации библиотеки pygame и Telegram-бота. Методы setup и destroy нам уже знакомы, метод логирования можно проигнорировать.

В методе start проверяем user_id, если пользователь — мы, то отправляем актуальную клавиатуру. В методе sendCapture определяем filename, создаем изображение с камеры и отправляем по chat_id. Метод get_capture нужен для отправки изображения и клавиатуры с актуальными коммандами. Метод sendVideo отвечает за отправку последнего записанного видео.

В методе captureVideo определяем filename и в систему отправляем запрос на запись видео с помощью утилиты ffmpeg. Метод get_video служит для отправки видео с отправкой промежуточных статусов.

Дальше рассмотрим ключевой метод sensorJob: здесь в бесконечном цикле считываем сигнал с датчика движения, выводим его на диод и при наличии сигнала сразу отправляем фото и включаем запись видео. Когда работа цикла завершается — отправляем сообщение об отключении датчика движения и актуальную клавиатуру.

Так как метод sensorJob работает из потока — здесь нам и понадобится переменная last_chat_id. В методе start_sensor запоминаем сhat_id, устанавливаем флаг работы датчика движения, запускаем поток с методом sensorJob и отправляем статус и актуальную клавиатуру.

В методе stop_sensor чистим last_chat_id, устанавливаем флаг работы датчика движения в ложное состояние, отключаем диод и отправляем актуальную клавиатуру. В методах mute/unmute_notifications переключаем в соответствующее положение флаг и отправляем статус и актуальную клавиатуру. На этом логика «Умной камеры» на текущий момент заканчивается. Теперь посмотрим на «Умную камеру» в действии.

Работа «Умной камеры»

Обратите внимание на время начала записи и получения фото и видео — оно очень большое для реальных кейсов, больше 5 минут. Это связано с параметрами в bot.pooling в методе main, а именно с параметром interval. Если оставить его по-умолчанию, то задержка будет минимальна и, как минимум, фото будет приходить практически моментально, но тогда возможны сбои из-за «Connection timeout» в работе Telegram-клиента и надо как-то обрабатывать это дополнительно.

Узкие места и возможные решения

  1. Необходима быстрая флешка, чтобы успевать сохранять видео;
  2. Желательно запись видео инициировать из Python напрямую, например, через библиотеку pyffmpeg, чтобы уменьшить время на инициализацию библиотеки при каждой записи видео;
  3. Хорошая камера, чтобы можно было рязглядеть нарушителя;
  4. Наличие быстрого интернета для более быстрого получения актуального видео.

Источник: temofeev.ru

Как отправить фото с камеры в Telegram — скрипт Domoticz

Простой скрипт отправки фото с камеры наружнего, или внутреннего наблюдения в чат telegram посредствам telegram bot. Отправка происходит при наличии какого либо условия, у меня например при срабатывании датчиков дверей, дверного звонка, почтового ящика и при нажатии виртуального переключателя в Domoticz.

Предполагается что у Вас уже настроен telegram bot и есть token бота.

Переходим в каталог скрипты/пользовательские скрипты и для удобства создаём папку telegramcam:

cd domoticz/scripts/customscripts

sudo mkdir telegramcam

cd telegramcam

Далее для каждой камеры создаём отдельный скрипт, например cameraZal, cameraPost, cameraParadnaja и т.п.:

И вставляем следующий код:

#!/bin/sh
SnapFile=»/var/tmp/cam3snapshot.jpg»
# Получаем скриншот камеры
sudo wget -O $SnapFile «http://192.168.1.2:8080/camsnapshot.jpg?idx=2»
# Отправляем скриншот в чат телеграм
curl -s -X POST «https://api.telegram.org/bot745941355:MMFGpcnklHplb9q6hw3d82lF$
#Задержка
sleep 5
# Удаляем скриншот
/bin/rm $SnapFile

Далее переходим в Domoticz и настраиваем действие для выполнения скрипта:

Теперь при открытии почтового ящика мы получим фото в чат бота в телеграм:

Можно так же добавить задержку срабатывания, несколько скриншотов

Источник: stupidhome.ru

Доработка оповещений в Telegtam со snapshot камер слежения

Предыстория. Приобрел я комплект видеонаблюдения Reolink. Несколько камер и NVR. Добавление в Home assistant не составило особого труда, используя стандартную интеграцию, даже при условии, что камеры имели внутренний IP рекордера. Для каждой камеры код имел следующий вид:

Однако пользуюсь я кастомным компонентом Reolink IP camera. Кроме самих камер, он позволяет добавить датчики движения на основе обнаружения движения моими камерами. В описании компонента все это есть.

Встал вопрос, как это можно использовать. Сразу захотелось, чтобы ХА присылал оповещение об активности в зоне видеонаблюдения в Telegram. Ну и соответственно прикреплял картинку с камеры. Я хотел именно картинку. Видео я могу посмотреть подключившись к NVR.

Но тут возникло две проблемы.
Первая: вопрос с «мусором», на который срабатывает камера. Опадающая листва, свет фар, пролетающая птичка и многое другое приводят к активации сенсора.
Вторая: Сервис camera.snapshot: оказался совершенно непригодным для этих целей, поскольку у него была задержка как и у видеопотока от 5 до 10 секунд.

Я подумал, что все очень просто и с первой проблемой справится условие, что сенсор активен в течение определенного времени, а со второй — прямая ссылка still_image_url: для каждой камеры (поскольку задержка в этом случае менее секунды).
Ну и для каждой камеры при выполнении условия, что ДД активен более ХХ секунд будет такой action:

— service: notify.telegram_stephan data: message: «Обнаружено движение вблизи дома.» data: photo: — url: http://192.168.1.243/cgi-bin/api.cgi?cmd=Snaprs=95270001DWZS2M8Ypassword=password caption: «Кажется, к нам гости.»

Но оказалось, что это абсолютно бесполезная автоматизация, поскольку в 99% срабатываний я получал картинку без признаков движения. Все логично, ведь снимок с камеры делался после ХХ секунд активности сенсора. А с учетом задержки, еще больше. К тому времени все уже «уходило».

Задача: Как только камера обнаруживает движение она делает снимок, а если движение продолжается более ХХ секунд, то в Telegram приходит именно этот снимок, сделанный ХХ секунд назад.

Решение: Поскольку хотелось сократить код до минимума (камер много, а будет еще больше), то пришлось проделать небольшие предварительные манипуляции с бинарниками (теми, которые ДД с камер).
В каждый бинарник а добавил attribute_templates: , в котором указана ссылка на статичную картинку с камеры (не мудрствовал и сделал аналогично первому примеру)

— platform: template sensors: motion_cam_1: friendly_name: Camera 1 motion device_class: motion value_template: «>» attribute_templates: still_image_url: «http://192.168.1.ХХХ/cgi-bin/api.cgi?cmd=Snaprs=95270001DWZS2M8Ypassword=password» delay_off: seconds: 1

Для каждой камеры делается свой URL. У меня NVR, поэтому меняется только channel=. Если камеры подключены напрямую, то будет меняться IP. Смотрите сами.

Теперь, для сохранения картинок я использовал сервис downloader.download_file
Если такого нет, то нужно в configuration.yaml добавить:

downloader: download_dir: www/downloads

Теперь можно перегружаться и делать автоматизации. Их всего две. Первая делает быстрый snapshot, вторая отсылает его при выполнении условия (условия на ваше усмотрение)

— alias: ‘Camera alarm snapshot’ trigger: — platform: state entity_id: — binary_sensor.motion_cam_1 — binary_sensor.motion_cam_2 — binary_sensor.motion_cam_3 — binary_sensor.motion_cam_4 from: ‘off’ to: ‘on’ action: — service: downloader.download_file data_template: url: «>» filename: ‘<>.jpg’ overwrite: true

— alias: ‘Camera_alarm’ trigger: — platform: state entity_id: — binary_sensor.motion_cam_1 — binary_sensor.motion_cam_2 — binary_sensor.motion_cam_3 — binary_sensor.motion_cam_4 to: ‘on’ for: «00:00:07» condition: — condition: state entity_id: group.family state: ‘not_home’ action: — service: notify.telegram_stephan data: message: «Обнаружено движение вблизи дома.» data: photo: — file: /config/www/downloads/<>.jpg caption: «Кажется, к нам гости.»

После этого, количество ложных срабатываний снизилось до 1%.
Насколько я знаю, у камер других производителей тоже есть возможность подключения ДД в Home assistant. Надеюсь, это кому то поможет.

Источник: sprut.ai

Оцените статью
Добавить комментарий