Телеграм-бот для домашнего видео-наблюдения из подручных материалов

Disclaimer


Эта статья содержит некоторое количество программного кода, написанного на языке Python. Ввиду того, что автор статьи по профессии является сисадмином, но не программистом — стиль и качество этого кода, могут вызвать проявление неконтролируемых эмоций у профессионалов. Пожалуйста, немедленно прекратите чтение если вид неаккуратного или неоптимального кода может негативно сказаться на вашем психическом состоянии.


Постановка задачи


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



Из всего перечисленного, было решено построить систему домашнего видео-наблюдения с функционалом оповещения о вторжении. В качестве платформы был выбран телеграм-бот. Бот имеет следующие преимущества перед другими возможными реализациями (веб, мобильное приложение):


  • Не требуется установки дополнительного клиентского ПО
  • Серверная часть может работать с приватным IP адресом через NAT, при этом предъявляются минимальные требования к подключению (вплоть до 3G модема)
  • Большая часть инфраструктуры находится на стороне сервис-провайдера, который за меня решил вопросы авторизации, безопасности итп...

С помощью беглого анализа интернет-публикаций, существующие решения обнаружены не были.


Шаг1. Операционная система


В качестве операционной системы был использован Raspbian. Для тех кто не в курсе, это такая сборка Debian, оптимизированная под работу на железе RaspberryPi. Система характеризуется стабильностью, большим количеством доступного прикладного ПО, хорошей документацией. Установка системы тривиальна и многократно описана в разных источниках. Я не буду останавливаться на этом подробно, скажу лишь что всё сводится к скачиваню образа диска и записи его на SD-карту. (Очевидно, что использовалась версия без GUI (lite)) Относительно настроек по-умолчанию, были выполнены следующие изменения:


  • Настройка OpenSSH сервера
  • Настройка часового пояса
  • Установка пакетов python3-pip, supervisor
    apt-get install python3-pip supervisor
  • Устновка модуля PyTelegramBotAPI
    pip3 install PyTelegramBotAPI

Шаг2. Захват изображений


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


apt-get install motion

Файл конфигурации (/etc/motion/motion.conf) настолько обширен, что в рамках данной статьи его невозможно описать полностью, остановлюсь лишь на тех параметрах которые значимы или были изменены от стандартных:


motion.conf
# Наша веб-камера
videodevice /dev/video0

# Разрешение камеры (из тех. характеристик)
width 1280
height 720

#Сколько раз в секунду снимать (от 2, до 100) 
#Влияет на загрузку CPU и определяет сколько сообщений вы получите в случае "вторжения"
framerate 4

#Сколько секунд после того как движение закончилось будет происходить съемка
event_gap 0

#Сохранять картинки в формате jpg со сжатием 75
output_pictures on
quality 75
picture_type jpeg

#Не сохранять видео
ffmpeg_output_movies off

#Каждые 30 секунд делать снимок (снапшот) "просто так"
snapshot_interval 30

#Обводить белым прямоугольником область в которой обнаружено движение
locate_motion_mode on
locate_motion_style box

#Путь  для хранения файлов
target_dir /var/lib/motion

#Формат имени файла для снапшота (для нас здесь важно наличие слова snapshot)
snapshot_filename %v-%Y%m%d%H%M%S-snapshot

#Важный момент! Имя файлов для снимков с движением.
#Я сильно упростил оригинальный вариант и у меня имена файлов имеют вид:
#Количество секунд с 1970 года + порядковый номер снимка за эту секунду
#таким образом имя файлов это всегда целое число которое только увеличивается
#это сильно упростило парсинг, сортировку итп...
picture_filename %s%q

Motion автоматически создает symlink на последний сохраненный снимок с именем lastsnap.jpg


Шаг 3. Программирование


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


В конфигурационном файле config.py хранится следующая информация: телеграм-api-токен (о том как его получить, подробно написано здесь), список ID пользователей для которых разрешен доступ, имя файла с последним снимком, путь к папке со всеми снимками.


config.py
token = '4345435465:AsdfzzsdxgsYnb8DxDtn2L5KjfePsXozjv-o0'
users=['1234567890','0987654321']
lastimage='/var/lib/motion/lastsnap.jpg'
motiondir='/var/lib/motion'

Собственно сам бот. В нем реализованы следующие функции:


  • Проверить, разрешен ли пользователю доступ
  • Сообщить неавторизованному пользователю его ID (чтобы он мог прийти с ним ко мне за доступом)
  • Показать последний сделанный снимок
  • Включить/выключить режим обнаружения
  • Сообщить всем пользователям бота, что режим работы изменен

bot.py
import config
import telebot
from telebot import types
import logging
import datetime

logger = telebot.logger
telebot.logger.setLevel(logging.INFO)  # Outputs debug messages to console.

bot = telebot.TeleBot(config.token, threaded=True)

### Функция проверки авторизации
def autor(chatid):
    strid = str(chatid)
    for item in config.users:
        if item == strid:
            return True
    return False

### Функция массвой рассылки уведомлений
def sendall(text):
    if len(config.users) > 0:
        for user in config.users:
            try:
                bot.send_message(user, text)
            except:
                print(str(datetime.datetime.now()) + ' ' + 'Ошибка отправки сообщения ' + text + ' пользователю ' + str(
                    user))

### Функция проверки режима
def checkmode():
    try:
        mode_file = open("mode.txt", "r")
        modestring = mode_file.read()
        mode_file.close()
        if modestring == '1':
            return True
        else:
            return False
    except:
        return False

print(str(datetime.datetime.now()) + ' ' + 'Я бот, я запустился!')
sendall(str(datetime.datetime.now()) + ' ' + 'Я бот, я запустился!')

### Главное меню
@bot.message_handler(commands=['Меню', 'start', 'Обновить'])
def menu(message):
    if autor(message.chat.id):
        markup = types.ReplyKeyboardMarkup()
        markup.row('/Обновить', '/Охрана')
        if checkmode():
            bot.send_message(message.chat.id, 'Режим охраны ВКЛ.', reply_markup=markup)
        else:
            bot.send_message(message.chat.id, 'Режим охраны ВЫКЛ.', reply_markup=markup)
        try:
            f = open(config.lastimage, 'rb')
            bot.send_photo(message.chat.id, f)
        except:
            bot.send_message(message.chat.id, 'Фоток нет')
    else:
        markup = types.ReplyKeyboardMarkup()
        markup.row('/Обновить')
        bot.send_message(message.chat.id, 'Тебе сюда нельзя. Твой ID: ' + str(message.chat.id), reply_markup=markup)

### Смена режима
@bot.message_handler(commands=['Охрана'])
def toggle(message):
    if autor(message.chat.id):
        try:
            if checkmode():
                last_file = open("mode.txt", "w")
                last_file.write('0')
                last_file.close()
                sendall('Пользователь ' + message.chat.first_name + ' выключил режим охраны')
            else:
                last_file = open("mode.txt", "w")
                last_file.write('1')
                last_file.close()
                sendall('Пользователь ' + message.chat.first_name + ' включил режим охраны')
        except:
            bot.send_message(message.chat.id, 'Ошибка смены режима')
            print(str(datetime.datetime.now()) + ' ' + "Ошибка смены режима")
        menu(message)

if __name__ == '__main__':
    bot.polling(none_stop=False)

Второй скрипт, запускается с некоторой периодичностью, проверяет есть ли необработанные jpg файлы без слова snapshot в имени и если включен режим обнаружения рассылает эти файлы всем пользователям бота.


sender.py
import datetime
import logging
import os
import time
import telebot
import config

logger = telebot.logger
telebot.logger.setLevel(logging.INFO)  # Outputs debug messages to console.
bot = telebot.TeleBot(config.token, threaded=True)

files = []
clearfiles = []
tosend = []
tosendfull = []

### Функция проверки режима
def checkmode():
    try:
        mode_file = open("mode.txt", "r")
        modestring = mode_file.read()
        mode_file.close()
        if modestring == '1':
            return True
        else:
            return False

    except:
        return False

## Функция массовой пассылки фотографий
def sendall(filename):
    for username in config.users:
        try:
            f = open(filename, 'rb')
            bot.send_photo(username, f)
        except:
            print(
                str(datetime.datetime.now()) + ' ' + 'Ошибка отправки файла ' + filename + ' пользователю ' + username)

## Функция записи последнего обработтанного файла
def writeproc(filename):
    try:
        last_file = open("last.txt", "w")
        last_file.write(filename)
        last_file.close()
        return last_file.close()
    except:
        return False

## Функция чтения последнего обработанного файла
def readproc():
    try:
        last_file = open("last.txt", "r")
        lasstring = last_file.read()
        last_file.close()
        lastint = str(lasstring)
        return lastint
    except:
        return -1

## Читаем последний обработанный файл
processed = readproc()
if processed == -1:
    print(str(datetime.datetime.now()) + ' ' + 'Не Удалось прочитать последний обработанный файл. Выходим')
    quit(2)

## Читаем список файлов
files = os.listdir(config.motiondir)
files = filter(lambda x: x.endswith('.jpg'), files)

## Очищаем список от снапшотов и расширений, сортируем
for file in files:
    if ('snapshot' in file) or ('last' in file) or ('-' in file):
        pass
    else:
        clearfile = file[:-4]
        clearfiles.append(clearfile)
        clearfiles.sort()

## Выбираем список необработанных файлов
for file in clearfiles:
    if int(file) > int(processed):
        tosend.append(file)

### Если есть что отправлять:
if len(tosend) > 0:
    try:
        if writeproc(tosend[-1]) == False:
            print(str(datetime.datetime.now()) + ' ' + 'Ошибка записи последнего элемента. Выходим!')
            quit(2)
        else:
            print(str(datetime.datetime.now()) + ' ' + 'Последний элемент записан успешно')
        ### Отправляем только если успешно записали последний - иначе будет бесконечная отправка
        ## Сначала проверяем режим
        if checkmode():

            ## Потом формируем список фалов с полным именем
            for filename in tosend:
                fullname = config.motiondir + '/' + filename + '.jpg'
                tosendfull.append(fullname)
            ## Потом отправляем неторопливо
            for filename in tosendfull:
                sendall(filename)
                time.sleep(1)
        else:
            print(str(datetime.datetime.now()) + ' ' + 'Режим отправки выключен')
    except:
        print(str(datetime.datetime.now()) + ' ' + 'Ошибка отправки')
else:
    print(str(datetime.datetime.now()) + ' ' + 'Нечего отправлять')

Шаг 4. Собираем всё в кучу
Все скрипты я разместил в каталоге /home/bigbro/bot. Для запуска, контроля и логирования использовал supervisor. Соответственно в каталоге /etc/supervisor/conf.d я создал файлы примерно такого вида:


[program:bot]
directory=/home/bigbro/bot
command=/usr/bin/python3 /home/bigbro/botbot.py
autostart=true
autorestart=true
stderr_logfile=/var/log/bot.err.log
stdout_logfile=/var/log/bot.out.log

Для периодического запуска скрипта отправки, можно было использовать cron, но из соображений единообразия я тоже запускаю его через supervisor и такой bash-скрипт:


#!/bin/bash
while true; do python3 sender.py ; sleep 30; done;

Результат
Всё работает ровно так как и было задумано:


image

Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 49
  • +1
    Супер.
    +

    Особенно умиляет в таких публикациях «порывшись у себя в столе я обнаружил...»
    • 0
      А что не так? Лично мне малинку подарили для одного стороннего проекта, который давно закончился, а камерой обзавелся когда учил английский по скайпу. Я знаю очень много людей, которые заказали себе RaspberryPi когда они только появились из любопытства, наигрались и забросили в стол.
      • +1
        Ну вообще-то распи 3 появилась не настолько давно, чтобы успеть забыть про неё в столе. Вроде и двух лет не прошло. А впрочем направление правильное, лучше использовать, чем просто валяется
        • 0
          Давно. В начале 16-го.
          • 0
            Вы лукавите :) ничего Вы не забыли. Она лежала на краю памяти, напоминая о себе время от времени( когда же ты меня к чему-то приспособишь). Впрочем это уже оффтопик
      • 0
        У меня на столе тоже не мало и Малинок и Апельсинок, а также их производны в виде ТВБоксов. Я уже давно использую аналогичное оборудование в качестве рабочих мест в офисах.
        Чего и вам всем советую.
      • 0
        Классное решение!
        Постараюсь повторить.
        Жаль нужно заказывать — в столе рыться бессмысленно)
        • 0
          Будут вопросы — обращайтесь.
        • –1
          В disclaimer так написано, как будто в статье использованы кадры из тяжелого гей-порно.))
          Спасибо, коллега, повторю ваш опыт.
          • 0

            Примерно так её и воспринимают знающие про генераторы, ContextManager'ы и прочий синтаксический сахар люди, да.

          • 0
            Если токен, который вы указали настоящий, то лучше затереть его. Любой может нарушить стабильность работы бота
            • +1
              Нет конечно. Равно как и ID пользователей. Но всё равно спасибо за предостережение.
            • 0
              Как раз вчера подобным образом пристроил свою Orange Pi.
              Была у меня xiaomi wifi camera, китайская версия. Связь через серваки китая часто была не радовала качеством, видео о сработке были короткими и не всегда удавалось разглядеть посетителя, да и программа их не всегда сообщала о сработке.
              В итоге вчера решил разобраться с этим делом. На камере активировал rtsp, на Orange Pi установил motioneye (который использует motion) и имеет приятный интерфейс с различными настройками. Настроил детектор движения, с сохранением видео и фото. Также В этой программе есть возможность отсылать по сработке сообщение на почту либо webhok. Вот через него я и организовал с помощью POST запроса отсылку себе в телеграмм фото сработки и видеоролик движения. Теперь даже если малинку украдут, фото и видео останутся в телеграмме.
              • –4
                Велосипед какой то, только еще и с деревянными колесами )))) А вот motion-project.github.io мне понравилось. Использую для других целей. А видео наблюдение в картинках не интересно. Есть давно круче видео наблюдение и не надо покупать дорогущие гаджеты. Полно экранное видео в hd качестве на любом устройстве и не важно где находишься!
                • 0
                  1 Автор ссылается на тот же проект motion
                  2 У большинства людей скорости интернета наверх для HD -30 FPS не хватит если картинка динамическая, а если статическая, то она не интересна.

                  • 0
                    В каком веке живем? У кого не хватает? не поверю! Если только где то далеко за уральским хребтом и то думаю врятли!
                • 0
                  Может кто подскажет, можно ли в motion как-либо отключить сработку на движение в момент переключения камеры в ночной режим и обратно?
                  • 0

                    lightswitch


                    Type: Integer
                    Range / Valid values: 0 — 100
                    Default: 0 (disabled)
                    Ignore sudden massive light intensity changes given as a percentage of the picture area that changed intensity. The value defines the picture areas in percent that will trigger the lightswitch condition. When lightswitch is detected motion detection is disabled for 5 picture frames. This is to avoid false detection when light conditions change and when a camera changes sensitivity at low light.

                  • +2

                    1 У motion есть режим отправки фото и видео по движению чтоб не запускать скрипт с периодичностью.
                    2 камера умеет захватывать и звук который тоже интересен.
                    Перед отправкой конвертим ffmpeg'ом видео и звук в понятные телеграмму форматы.
                    На самом деле отдавать целую малину под такую фигню как то жирно.
                    Погугли всякие "умные дома" на малине плюсом к motion

                    • 0
                      Наличие дома гиперактивного котенка, увы, обесценивает идею )
                      • 0
                        Универсально решения конечно нет, но продукт очень гибкий — можно задать минимальное количество пикселей, которые должны измениться чтобы произошло срабатывание, можно задавать маски с мертвыми зонами или наоборот маски с зонами в которых должно произойти движение.итд итп
                        • 0
                          Действительно, как-то не подумал, кот, в любом случае, значительно меньше человека.
                          PS: а о том что он сорвал занавески или стянул со стола скатерть, со всем что на нем находилось, удобно знать заранее, до того как приехал домой.
                      • 0

                        Спасибо за статью, сейчас как раз подобное делаю для наблюдения за гаражом. В принципе у меня почти так же вышло, но всё равно интересно. Возьму себе supervisor :)

                        • 0
                          Ну вообще для этого правильнее sytemd использовать. supervisor это моё личное предпочтение
                        • +1
                          Больше года назад организовал себе на Rpi3 и совместимой шлейфовой ИК-камере видеоглазок на motion с отправкой скриншотов в я-диск по движению. Rpi встроен внутрь двери. Потом добавил ИК-диод (нужна длина 900+нм чтобы его не было видно вообще никак). Теперь видно в любое время дня и ночи происходящее за дверью вне зависимости от освещения. Сделал скрипт для автозачистки при переполнении хранилища.
                          Из последнего заметил и добавил motioneye. Полезно например для просмотра текущего скриншота (motion позволяет смотреть только текущее видео).
                          • +2
                            У меня в столе не нашлось камеры, но зато нашелся первый распберри и геркон (стоимость в магазине 50 р.). Геркон поставил на входную дверь, соединил с пинами GND и ближайшим GPIO. Далее слежу за состоянием GPIO. При изменении состояния отправляю сообщение почтой/телеграммой. Наверное последую вашему опыту и прикручу к этой связке камеру.
                            • 0
                              Занимался недавно похожим, правда без Motion просто с mjpg-streamer.
                              Платформы TL-WR902AC и Raspberry Pi 2 Model B, на которые установил LEDE (OpenWrt). Telegram bot (черновой, но работающий вариант) написал сам на LUA (+ uHTTPd). Кроме картинок с камеры бот умеет выполнять modbus команды и другие фокусы.

                              • +1
                                Рассказал бы про «modbus команды и другие фокусы». Многим наверное интересно.
                                • 0
                                  Да, было бы интересно узнать поподробнее об этом в формате статьи.
                                • 0
                                  Мне показалось удобнее писать в mp4 по движению и по оканчании файла слать в телеграм:
                                  on_movie_end /usr/local/bin/message2telegram.sh file "#motion detected on DoorEye at %H:%M:%S %d-%m-%Y" "%f"
                                  

                                  Плюсы: до 10Мб телеграмом расцениваются как gif. На видео лучше видно происходящее.
                                • 0
                                  Доброго дня!
                                  Большое спасибо за интересную статью.
                                  Начал писать по вашей статье. Получается в несколько раз меньше строк. С удовольствием обсудил бы оптимизацию кода.
                                  У меня сразу возник вопрос: как можно ботом отправлять сообщения непосредственно пользователю по его номеру а не в чат? У меня не получилось.
                                  • 0
                                    И вам!
                                    Если Вы увидели какую-то реальную проблему в коде, которая может мешать стабильности или безопасности — я буду очень вам благодарен за эту информацию.
                                    • 0

                                      Нет, речь пока идет только про оптимизацию, я глубоко пока не анализировал.
                                      Вот, например:


                                      users = [123567890, 123567891]
                                      
                                      def is_known(user):  # Функция проверки авторизации
                                          return user in config.users
                                      
                                      def sendall(text):  # Функция массвой рассылки уведомлений
                                          for user in config.users:
                                              try:
                                                  bot.send_message(user, text)
                                              except Exception as exc:
                                                  print('%s Ошибка отправки сообщения %s пользователю %d: %s'
                                                        % (str(datetime.datetime.now()).split('.')[0], text, user, exc))

                                      Идеологию мое преобразование не меняет, но вод код становится приятней 'на ощупь'.
                                      Но это мое субъективное мнение.
                                      Я тоже сисадмин, но в свое время окончил вуз на программиста-системщика.
                                      Пайтон изучаю самостоятельно, но полюбил его и чувствую, что это взаимно.

                                  • 0
                                    Вдогонку (редактировать сообщение не дает):
                                    т.е. себе я могу отправить сообщение, т.к. бота создал я, а кому то другому не могу. Получаю ошибку:
                                    A request to the Telegram API was unsuccessful. The server returned HTTP 403 Forbidden.
                                    Response body: [b'{«ok»:false,«error_code»:403,«description»:«Forbidden: bot can\'t initiate conversation with a user»}']
                                    • 0
                                      Всё так. Дело не в том что вы его создали а в том что сами инициировали с ним диалог. Человек которому вы хотите написать — должен так же сначала сам пообщаться с ботом.
                                      • 0
                                        Спасибо.
                                        Понятно.
                                    • 0
                                      Очень интересная статья, спасибо! Интересовался тем, чтобы сделать аналогичную штуку, но не знал с чего подступиться. Сейчас рассмотрел свои запасы. Малину у себя не нашёл (у меня её никогда не было, впрочем), зато нашёл аналогичную камеру и карточку, теперь осталось раздобыть платформу, на которой можно сделать то, что сделано у вас.
                                      • +1
                                        Делал аналогичное решение. У себя я дополнительно сделал анализ клиентов wi-fi, если устройств из списка нет охрана автоматом включается, если есть — бот ничего не шлёт. Правда у меня несколько комментариев проще все, ip-камера умеет сама складывать фотки на ftp при движении в зоне. Мне осталось лишь их отправить.
                                      • 0

                                        Спасибо за заметку.
                                        У меня тут как раз Raspberry PI(правда, постарше, вторая ещё) висит, на которую заведены и видеонаблюдение, и сбор данных с нескольких датчиков температуры/влажности, раскиданных по дому, и скоро должен приехать пучок релюшек Sonoff для управления светом и прочими
                                        Я как раз подумывал ко всему этому прикрутить телеграм-бота, а тут ваша статья.


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


                                        множество сработок за день


                                        И это ещё не самый "активный" день.
                                        С одной стороны — все эти сработки неплохо иметь в архиве, чтобы, например, во время отпуска можно было вечером за небольшое время посмотреть "ретроспективу" за день. С другой стороны — если каждую сработку показывать в телеграме, то поток сообщений будет слишком густым и малополезным.


                                        Поэтому я пока ещё работаю над всем этим и думаю, как сделать правильнее. Пока видятся два возможных пути — либо прикручивать второй слой анализа картинок(например, ZoneMinder), либо ставить дополнительные датчики движения, и заводит их на "тревожные" входы регистратора.


                                        В общем, копать — не перекопать 8)

                                        • 0
                                          За статью спасибо.
                                          На правах баг-репорта:
                                          если не создать last.txt и не записать туда число, то sender.py не будет работать?
                                          • +1
                                            Если включить в motion web контроль
                                            motion.conf
                                            webcontrol_localhost on
                                            webcontrol_port 8080
                                            stream_localhost off
                                            stream_port 8081

                                            то возможно управлять motion сервисом через requests
                                            примерные запросы
                                            Остановить motion detection
                                            http ://localhost:8080/1/detection/pause
                                            Запустить moton detection
                                            http ://localhost:8080/1/detection/start
                                            Текущий статус
                                            http ://localhost:8080/1/detection/status
                                            Создать snapshot можно вызывать перед отправкой вместо того, чтобы создавать каждые 30 минут
                                            http ://localhost:8080/1/action/snapshot
                                            • 0
                                              Добрый день!

                                              Поясните пожалуйста, зачем это делать?
                                              Гораздо удобнее управлять через Телеграм.
                                              • 0
                                                Так прямо через Телеграм и будет управляться, просто в скрипте выполняется requests.get(url) и когда система снята с охраны motion ничего сохранять на флешку не будет.
                                                P.S. естественно правильнее будет stream_localhost on — я ошибся
                                            • 0
                                              Чего-то не детектирует он у меня движение. Фотки послать может, а движение слабовато как-то, надо пузо в обьектив сунуть, чтобы уверенно сработал. Да, знаю, что можно подстроить, но очень сильно загрублено по дефолту.
                                              Ну и еще поворчу, а то автору счастья не будет — похоже, не пробовал никто повторить — одни критики.
                                              Итак, в строчке:
                                              command=/usr/bin/python3 /home/bigbro/botbot.py
                                              слеша не хватает, догадайтесь, где
                                              Motion запускать надо при загрузке, с sudo, сам по себе он в загрузку при инсталляции не пропишется. Да и инициализацию видеокамеры тоже бы неплохо, чтобы появилось /dev/video0, в случае RPI Camera Module sudo modprobe bcm2835-v4l2
                                              И еще. sudo apt-get upgrade надо сделать в самом начале, после установки системы на карту. И не работать под рутом. И добавить настройку вайфай, провода сейчас все же в прошлое уходят.
                                              Все остальное работает отлично, не к чему придраться. Спасибо огромное!
                                              • 0
                                                Мало у кого есть такой комплект. Мало кто пробовал поэтому. Я попробовал, что-то заработало (могу получать текущее изображение), что-то не доделал (сигнал при срабатывании детектора), но пока забросил ввиду не особо большой актуальности на сей момент (не NAT, в любой момент могу получить как текущую картинку так и результаты детекции в я.диске, кстати, не соглашусь про грубость срабатывания, threshold в 1500 изменённых пикселей по умолчанию это довольно хорошо, на уровне детекции даже не кошки за дверью а чего-то поменьше, летающих насекомых, вопрос в разрешении, норма — FULLHD с его ~2млн пикселей и, возможно, в частоте кадров, для снижения нагрузки у меня 1 кадр/c).
                                                Куда хуже в моей связке(rpi3+csi-камера) периодическое зависание службы motion по непонятным причинам (в логе в этот момент фигурирует вотчдог) + часто рэндомно ставящаяся (часто недостаточная, с излишней справиться было проще) яркость, из-за чего может не срабатывать детекция, но тут уже дело скорее в V4L2. Пришлось писать несколько скриптов для определения наличия нормального изображения в кадре и его параметров (спасибо imagemagick) для передёргивания службы при её зависании либо при слишком тёмном/светлом изображении. Ну и motioneye помогает.
                                                Плюс необходимые скрипты для очистки локального каталога с картинками motion и корзины я-диска. Без этого всё ломается через какое-то время.
                                              • 0
                                                Вот мой вариант бота для OpenWrt, работает из коробки, взять можно на GitHub.
                                                Нужен только доступ в shell, а так-же curl + json парсер (в идеале, но можно и без него через grep/awk/sed сделать), т.е. будет работать практически на любых железках.
                                                Команды оформлены в виде плагинов для примера, а в самом телеграме сразу кнопочки рисует.

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