London

<<< Назад

Уведомления ZoneMinder без модуля.

Сделал себе уведомления от камер из ZoneMinder без использования модуля для MajorDoMo

Захотелось мне, чтоб домофон отправлял в телеграм фото и видео звонящего.
Когда только звонят - отправляю фото, когда заканчивается движение на домофоне - отправляю видео.
Потом домофон уходит в "черный экран" и движения нет.
Попробовал сначала модуль ZoneMinder Events для MajorDoMo, но, не понравилось, что он проверяет новые Events постоянно долбя базу MySQL.
Решил сделать без его использования.

Создал объект с двумя методами, sendPhoto и sendVideo.

sendPhoto:

include_once(DIR_MODULES . 'telegram/telegram.class.php');
playSound('door_bell',1);
$time=$params['time'];
$telegram_module = new telegram();
file_put_contents('cms/cached/tmpdomofon.jpg',file_get_contents('http://localhost/zm/cgi-bin/zms?mode=single&monitor='.$params['MonitorId']));
$telegram_module->sendImageToUser(xxx, 'cms/cached/tmpdomofon.jpg', 'Звонят в домофон от '.date('d.m.Y H:i:s',$time));

sendVideo:

include_once(DIR_MODULES . 'telegram/telegram.class.php');
$EventId=$params['EventId'];
$time=$params['time'];
$telegram_module = new telegram();
file_put_contents('cms/cached/tmpdomofonvideo.mp4',file_get_contents('http://localhost/zm/index.php?mode=mp4&eid='.$EventId.'&view=view_video'));
$telegram_module->sendVideoToUser(xxx, 'cms/cached/tmpdomofonvideo.mp4', 'Запись звонка в домофон от '.date('d.m.Y H:i:s',$time));

В ZoneMinder надо включить запись mp4 при event, чтобы скачиваение видео было доступно сразу после события.

Далее, создаём в linux perl скрипт следующего содержания:

#!/usr/bin/env perl

use strict;
use warnings;
use ZoneMinder;
use Switch;

$| = 1;

my @monitors;
logInit();
logSetSignal();

my $dbh = zmDbConnect();

my $oldstate = 0;
my $oldtime = 0;

my $phototime;

Info('Zm-alarm daemon starting');

my $sql = "SELECT * FROM Monitors
  WHERE find_in_set( `Function`, 'Modect,Mocord,Nodect' )".
  ( $Config{ZM_SERVER_ID} ? 'AND ServerId=?' : '' )
  ;

my $sth = $dbh->prepare_cached( $sql )
  or die( "Can't prepare '$sql': ".$dbh->errstr() );

my $res = $sth->execute()
  or die( "Can't execute '$sql': ".$sth->errstr() );

while ( my $monitor = $sth->fetchrow_hashref() ) {
    push( @monitors, $monitor );
}
while (1) {
        foreach my $monitor (@monitors) {
               # Check shared memory ok
               if ( !zmMemVerify( $monitor ) ) {
                 zmMemInvalidate( $monitor );
                 next;
                }

                my $monitorState = zmGetMonitorState($monitor);
                printState($monitor->{Id}, $monitor->{Name}, $monitorState);
        }
        sleep 1;
}

sub printState {
        my ($monitor_id, $monitor_name, $state) = @_;
        my $localtime = localtime();
        my $time = time();
#        switch ($state) {
#                case 0 { Info("$localtime - $monitor_name:\t Idle!") }
#                case 1 { Info("$localtime - $monitor_name:\t Prealarm!") }
#                case 2 { Info("$localtime - $monitor_name:\t Alarm!") }
#                case 3 { Info("$localtime - $monitor_name:\t Alert!") }
#        }

        if ($monitor_id == 7) {
                if ($state == 0 && $oldstate != 0) {
                        my $sql2 = "select Id from Events where MonitorId = ".$monitor_id." order by id DESC limit 1";
                        my $sth2 = $dbh->prepare( $sql2 )
                          or die( "Can't prepare '$sql': ".$dbh->errstr() );
                        my $res2 = $sth2->execute()
                          or die( "Can't execute '$sql': ".$sth2->errstr() );
                        my $EventId;
                        while (my @row = $sth2->fetchrow_array() ) {
        #                   push( @EventIds, $ids );
                                $EventId = $row[0];
                        }
                        Info("Need to send video $EventId");
                        sleep(2);
                        system("/usr/bin/wget 'http://localhost/api/method/domofon.sendVideo?MonitorId=$monitor_id&EventId=$EventId&time=$phototime' -qO /dev/null");
                        sleep(105-($time-$oldtime));
                } elsif ($state != 0 && $oldstate == 0) {
                        $phototime=$time;

                        Info("Need to send Photo");
                        sleep(2);
                        system("/usr/bin/wget 'http://localhost/api/method/domofon.sendPhoto?MonitorId=$monitor_id&time=$phototime' -qO /dev/null");
                        $oldtime=$time;

                }
                $oldstate=$state;
        }
}

При смене статуса с Idle на Alarm - через 2 секунды единожды вызываем sendPhoto
При смене статуса с Alert на Idle - через 2 секунды вызываем sendVideo и "засыпаем" на время до 105 секунд (т.к., я не хочу получать уведомления от домофона чаще, чем раз в 105 секунд)

Данный скрипт на перле сохраняем, например, в домашней директории.
Даём ему права на запуск, например, chmod +x /home/pi/za-alarm.pl
Добавляем его в автозапуск, т.к., он постоянно должен быть запущен.

Всё, теперь получаем следущую картину:

Итого, цель достигнута, получаю уведомления от домофона в телеграм, при этом, не дергая базу с помощью предлагаемого модуля для мдм.
Ну и видео получаю сразу после завершения движения на камере.

Если Вам понравилась статья, не забывайте ставить лайк:) Это стимулирует писать ещё ;-)

Обсуждение (2) (12)

Смотрите так же:
14.10.2020 Делаем видеодомофон в Homekit
07.10.2020 Модернизируем сенсорный выключатель LIVOLO для умного дома. Выводим нулевой провод, для нормального питания.
14.05.2020 Подписка на топики mqtt
08.05.2020 Мониторинг хостов с миротика

Ашукино, Россия

На форуме: London