Guest User

Untitled

a guest
Jul 15th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.28 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2.  
  3. use strict;
  4.  
  5. use ZoneMinder;
  6. use warnings;
  7. use DBI;
  8. use Data::Dumper;
  9. use Try::Tiny;
  10. use JSON;
  11. use Net::MQTT::Simple::Auth;
  12.  
  13. $| = 1;
  14.  
  15. open F, ">/tmp/hatrigger.pid";
  16. print F $$;
  17. close F;
  18.  
  19.  
  20. my $dbhost= "192.168.1.1";
  21. my $dbdriver = "mysql";
  22. my $database = "zoneminder";
  23. my $dbuser = "zoneminder";
  24. my $dbpassword = "CHANGE";
  25. my $mqtthost = "CHANGE:1883";
  26. my $mqttuser = "homeassistant";
  27. my $mqttpassword = "CHANGE";
  28. my $mqtt;
  29.  
  30. my $reloadCamerasInSeconds = 300;
  31.  
  32. my @monitors;
  33. my $loop=$reloadCamerasInSeconds;
  34.  
  35. sub connectMQTT
  36. {
  37. if (!defined $mqtt || !$mqtt->tick(0))
  38. {
  39. print("Connecting to MQTT Server...\n");
  40. $mqtt = Net::MQTT::Simple::Auth->new($mqtthost, $mqttuser, $mqttpassword);
  41. #if ($mqtt->tick())
  42. #{
  43. # refreshCameras();
  44. #};
  45. };
  46. }
  47.  
  48. sub fetchCameras
  49. {
  50. my $dbh = DBI->connect("DBI:$dbdriver:$database:$dbhost",$dbuser, $dbpassword) or die $DBI::errstr;
  51. 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)";
  52. my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
  53. my $res = $sth->execute() or die( "Can't execute '$sql': ".$sth->errstr() );
  54. return $sth;
  55. }
  56.  
  57.  
  58. sub sendPayload
  59. {
  60. my($topic, $state) = @_;
  61. $mqtt->retain($topic => $state);
  62. print("Topic: " .$topic ." - Payload: " .$state. "\n");
  63. }
  64.  
  65. sub sendState
  66. {
  67. my($camera, $state) = @_;
  68. $camera =~ s/[^a-zA-Z0-9]//g;
  69. my $topic = "homeassistant/binary_sensor/${camera}/state";
  70. sendPayload($topic, $state);
  71. }
  72.  
  73. sub setupCamera
  74. {
  75. my($camera) = @_;
  76. my $orig_name = $camera;
  77. $camera =~ s/[^a-zA-Z0-9]//g;
  78. my $topic = "homeassistant/binary_sensor/${camera}/config";
  79. my %camera_hash = (
  80. "name" => $orig_name ." Alarm",
  81. "device_class" => "motion",
  82. "state_topic" => "homeassistant/binary_sensor/${camera}/state",
  83. "payload_on" => "alarm",
  84. "payload_off" => "idle"
  85. );
  86. my $json = encode_json \%camera_hash;
  87. sendPayload($topic, $json);
  88. }
  89.  
  90. sub getState
  91. {
  92. my($monitor) = @_;
  93. try {
  94. return 0 if ( !zmMemVerify( $monitor ) );
  95. return zmInAlarm($monitor);
  96. } catch {
  97. return 0;
  98. };
  99. }
  100.  
  101. sub refreshCameras
  102. {
  103. try {
  104. my $sth = fetchCameras();
  105. @monitors = ();
  106. while ( my $monitor = $sth->fetchrow_hashref() )
  107. {
  108. $monitor->{AlarmNotified} = 0;
  109. setupCamera( $monitor->{Name} );
  110. my $state;
  111. if (getState($monitor))
  112. {
  113. $state="alarm";
  114. } else {
  115. $state="idle";
  116. }
  117. sendState( $monitor->{Name}, $state );
  118. push( @monitors, $monitor );
  119. }
  120. } catch {
  121. print("Cannot refresh cameras - ignoring refresh\n");
  122. };
  123. $loop = 0;
  124. }
  125.  
  126. while( 1 )
  127. {
  128. connectMQTT();
  129. if ($loop >= $reloadCamerasInSeconds)
  130. {
  131. refreshCameras();
  132. }
  133. foreach my $monitor ( @monitors )
  134. {
  135. if (getState($monitor))
  136. {
  137. if ($monitor->{AlarmNotified} == 0)
  138. {
  139. $monitor->{AlarmNotified} = 1;
  140. sendState($monitor->{Name}, "alarm");
  141. print( "Monitor ".$monitor->{Name}." has alarmed\n" );
  142. }
  143. } else {
  144. if ($monitor->{AlarmNotified} == 1)
  145. {
  146. $monitor->{AlarmNotified} = 0;
  147. sendState( $monitor->{Name}, "idle" );
  148. print( "Monitor ".$monitor->{Name}." has returned to normal\n" );
  149. }
  150. }
  151. }
  152. $loop++;
  153. sleep( 1 );
  154. }
Add Comment
Please, Sign In to add comment