Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl -w
- use strict;
- use ZoneMinder;
- use warnings;
- use DBI;
- use Data::Dumper;
- use Try::Tiny;
- use JSON;
- use Net::MQTT::Simple::Auth;
- $| = 1;
- open F, ">/tmp/hatrigger.pid";
- print F $$;
- close F;
- my $dbhost= "192.168.1.1";
- my $dbdriver = "mysql";
- my $database = "zoneminder";
- my $dbuser = "zoneminder";
- my $dbpassword = "CHANGE";
- my $mqtthost = "CHANGE:1883";
- my $mqttuser = "homeassistant";
- my $mqttpassword = "CHANGE";
- my $mqtt;
- my $reloadCamerasInSeconds = 300;
- my @monitors;
- my $loop=$reloadCamerasInSeconds;
- sub connectMQTT
- {
- if (!defined $mqtt || !$mqtt->tick(0))
- {
- print("Connecting to MQTT Server...\n");
- $mqtt = Net::MQTT::Simple::Auth->new($mqtthost, $mqttuser, $mqttpassword);
- #if ($mqtt->tick())
- #{
- # refreshCameras();
- #};
- };
- }
- sub fetchCameras
- {
- my $dbh = DBI->connect("DBI:$dbdriver:$database:$dbhost",$dbuser, $dbpassword) or die $DBI::errstr;
- my $sql = "select M.*, max(E.Id) as LastEventId from Monitors as M left join Events as E on M.Id = E.MonitorId where Enabled=1 group by (M.Id)";
- 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() );
- return $sth;
- }
- sub sendPayload
- {
- my($topic, $state) = @_;
- $mqtt->retain($topic => $state);
- print("Topic: " .$topic ." - Payload: " .$state. "\n");
- }
- sub sendState
- {
- my($camera, $state) = @_;
- $camera =~ s/[^a-zA-Z0-9]//g;
- my $topic = "homeassistant/binary_sensor/${camera}/state";
- sendPayload($topic, $state);
- }
- sub setupCamera
- {
- my($camera) = @_;
- my $orig_name = $camera;
- $camera =~ s/[^a-zA-Z0-9]//g;
- my $topic = "homeassistant/binary_sensor/${camera}/config";
- my %camera_hash = (
- "name" => $orig_name ." Alarm",
- "device_class" => "motion",
- "state_topic" => "homeassistant/binary_sensor/${camera}/state",
- "payload_on" => "alarm",
- "payload_off" => "idle"
- );
- my $json = encode_json \%camera_hash;
- sendPayload($topic, $json);
- }
- sub getState
- {
- my($monitor) = @_;
- try {
- return 0 if ( !zmMemVerify( $monitor ) );
- return zmInAlarm($monitor);
- } catch {
- return 0;
- };
- }
- sub refreshCameras
- {
- try {
- my $sth = fetchCameras();
- @monitors = ();
- while ( my $monitor = $sth->fetchrow_hashref() )
- {
- $monitor->{AlarmNotified} = 0;
- setupCamera( $monitor->{Name} );
- my $state;
- if (getState($monitor))
- {
- $state="alarm";
- } else {
- $state="idle";
- }
- sendState( $monitor->{Name}, $state );
- push( @monitors, $monitor );
- }
- } catch {
- print("Cannot refresh cameras - ignoring refresh\n");
- };
- $loop = 0;
- }
- while( 1 )
- {
- connectMQTT();
- if ($loop >= $reloadCamerasInSeconds)
- {
- refreshCameras();
- }
- foreach my $monitor ( @monitors )
- {
- if (getState($monitor))
- {
- if ($monitor->{AlarmNotified} == 0)
- {
- $monitor->{AlarmNotified} = 1;
- sendState($monitor->{Name}, "alarm");
- print( "Monitor ".$monitor->{Name}." has alarmed\n" );
- }
- } else {
- if ($monitor->{AlarmNotified} == 1)
- {
- $monitor->{AlarmNotified} = 0;
- sendState( $monitor->{Name}, "idle" );
- print( "Monitor ".$monitor->{Name}." has returned to normal\n" );
- }
- }
- }
- $loop++;
- sleep( 1 );
- }
Add Comment
Please, Sign In to add comment