mirror of
https://github.com/Roller-Network/asterisk-contact-id.git
synced 2026-06-29 11:32:46 -06:00
First upload
This commit is contained in:
parent
478e1f385a
commit
6b09d023ee
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
.DS_Store
|
||||
651
asteriskcontactid.pl
Executable file
651
asteriskcontactid.pl
Executable file
|
|
@ -0,0 +1,651 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# asteriskcontactid.pl
|
||||
# https://github.com/WillCodeForCats/asterisk-contact-id
|
||||
#
|
||||
# A Contact ID handler for Asterisk's AlarmReceiver() application.
|
||||
# https://wiki.asterisk.org
|
||||
#
|
||||
# Uses rcell-smsclient for direct SMS notifications
|
||||
# https://github.com/WillCodeForCats/rcell-smsclient
|
||||
#
|
||||
#
|
||||
|
||||
use strict;
|
||||
use IO::Dir;
|
||||
use DBI;
|
||||
use DateTime::Format::Strptime;
|
||||
use DateTime::Format::MySQL;
|
||||
use MIME::Lite;
|
||||
|
||||
my $spoolDir = '/var/spool/asterisk/alarmreceiver';
|
||||
my $dbi = "DBI:mysql:host=localhost;database=asterisk";
|
||||
my $dbuIser = "asterisk";
|
||||
my $dbiPassword = "qwertyuiop123456789";
|
||||
|
||||
my $emailFrom = 'alarmreceiver@example.com';
|
||||
my $timezone = 'America/Los_Angeles';
|
||||
|
||||
# account names
|
||||
my %accts = (
|
||||
1111 => "Account 1111",
|
||||
2222 => "Another Account 2222",
|
||||
3333 => "Third Account 3333",
|
||||
);
|
||||
|
||||
# who to notify per account
|
||||
# 10-digit cell number for SMS or email address only
|
||||
my %notify = (
|
||||
1111 => [
|
||||
'user@example.com', '5555551234',
|
||||
],
|
||||
2222 => [
|
||||
'user@example.com', '5555551234',
|
||||
'user2@example.com', '5555551234',
|
||||
],
|
||||
3333 => [
|
||||
'user@example.com', '5555551234',
|
||||
'user3@example.com', '5555551234',
|
||||
],
|
||||
);
|
||||
|
||||
# Contact ID Event Codes
|
||||
my %events = (
|
||||
# 100 - Medical Alarms
|
||||
100 => "Medical",
|
||||
101 => "Personal Emergency",
|
||||
102 => "Fail To Report In",
|
||||
|
||||
# 110 - Fire Alarms
|
||||
110 => "Fire",
|
||||
111 => "Smoke",
|
||||
112 => "Combustion",
|
||||
113 => "Water Flow",
|
||||
114 => "Heat",
|
||||
115 => "Pull Station",
|
||||
116 => "Duct",
|
||||
117 => "Flame",
|
||||
118 => "Near Alarm",
|
||||
|
||||
# 120 - Panic Alarms
|
||||
120 => "Panic",
|
||||
121 => "Duress",
|
||||
122 => "Silent",
|
||||
123 => "Audible",
|
||||
124 => "Duress - Access Granted",
|
||||
125 => "Diress - Egress Granted",
|
||||
|
||||
# 130 - Burglar Alarms
|
||||
130 => "Burglary",
|
||||
131 => "Perimeter",
|
||||
132 => "Interior",
|
||||
133 => "24 Hour",
|
||||
134 => "Entry/Exit",
|
||||
135 => "Day/Night",
|
||||
136 => "Outdoor",
|
||||
137 => "Tamper",
|
||||
138 => "Near Alarm",
|
||||
139 => "Intrusion Verifier",
|
||||
|
||||
# 140 - General Alarm
|
||||
140 => "General Alarm",
|
||||
141 => "Polling Loop Open",
|
||||
142 => "Polling Loop Short",
|
||||
143 => "Expansion Module Failure",
|
||||
144 => "Sensor Tamper",
|
||||
145 => "Expansion Module Tamper",
|
||||
146 => "Silent Burglary",
|
||||
147 => "Sensor Supervision Failure",
|
||||
|
||||
# 150 and 160 - 24 Hour Non-Burglary
|
||||
150 => "24 Hour Non-Burglary",
|
||||
151 => "Gas Detected",
|
||||
152 => "Refrigeration",
|
||||
153 => "Loss of Heat",
|
||||
154 => "Water Leak",
|
||||
155 => "Foil Break",
|
||||
156 => "Day Trouble",
|
||||
157 => "Low Bottled Gas Level",
|
||||
158 => "High temp",
|
||||
159 => "Low temp",
|
||||
161 => "Loss of air flow",
|
||||
162 => "Carbon Monoxide detected",
|
||||
163 => "Tank level",
|
||||
|
||||
# 200 and 210 - Fire Supervisory
|
||||
200 => "Fire Supervisory",
|
||||
201 => "Low Water Pressure",
|
||||
202 => "Low CO2",
|
||||
203 => "Gate Valve Sensor",
|
||||
204 => "Low Water Level",
|
||||
205 => "Pump Activated",
|
||||
206 => "Pump Failure",
|
||||
|
||||
# 300 and 310 - System Troubles
|
||||
300 => "System Trouble",
|
||||
301 => "AC Loss",
|
||||
302 => "Low System Battery",
|
||||
303 => "RAM Checksum Bad",
|
||||
304 => "ROM Checksum Bad",
|
||||
305 => "System Reset",
|
||||
306 => "Panel Programming Changed",
|
||||
307 => "Self-Test Failure",
|
||||
308 => "System Shutdown",
|
||||
309 => "Battery Test Failure",
|
||||
310 => "Ground Fault",
|
||||
311 => "Battery Missing/Dead",
|
||||
312 => "Power Supply Overcurrent",
|
||||
313 => "Engineer Reset",
|
||||
|
||||
# 320 - Sounder / Relay Troubles
|
||||
320 => "Sounder/Relay Trouble",
|
||||
321 => "Bell 1 Trouble",
|
||||
322 => "Bell 2 Trouble",
|
||||
323 => "Alarm Relay Trouble",
|
||||
324 => "Trouble Relay",
|
||||
325 => "Reversing Relay Trouble",
|
||||
326 => "Notification Appliance Ckt. #3 Trouble",
|
||||
327 => "Notification Appliance Ckt. #4 Trouble",
|
||||
|
||||
# 330 and 340 - System Peripheral Trouble
|
||||
330 => "System Peripheral Trouble",
|
||||
331 => "Polling Loop Open",
|
||||
332 => "Polling Loop Short",
|
||||
333 => "Expansion Module Failure",
|
||||
334 => "Repeater Failure",
|
||||
335 => "Local Printer Out Of Paper",
|
||||
336 => "Local Printer Failure",
|
||||
337 => "Exp. Module DC Loss",
|
||||
338 => "Exp. Module Low Batt.",
|
||||
339 => "Exp. Module Reset",
|
||||
341 => "Exp. Module Tamper",
|
||||
342 => "Exp. Module AC Loss",
|
||||
343 => "Exp. Module Self-Test Fail",
|
||||
344 => "RF Receiver Jam Detect",
|
||||
|
||||
# 350 and 360 - Communication Troubles
|
||||
350 => "Communication Trouble",
|
||||
351 => "Telco 1 Fault",
|
||||
352 => "Telco 2 Fault",
|
||||
353 => "Long Range Radio Xmitter Fault",
|
||||
354 => "Failure To Communicate Event",
|
||||
355 => "Loss Of Radio Supervision",
|
||||
356 => "Loss Of Central Polling",
|
||||
357 => "Long Range Radio Vswr Problem",
|
||||
|
||||
# 370 - Protection Loop
|
||||
370 => "Protection Loop",
|
||||
371 => "Protection Loop Open",
|
||||
372 => "Protection Loop Short",
|
||||
373 => "Fire Trouble",
|
||||
374 => "Exit Error Alarm (Zone)",
|
||||
375 => "Panic Zone Trouble",
|
||||
376 => "Hold-Up Zone Trouble",
|
||||
377 => "Swinger Trouble",
|
||||
378 => "Cross-Zone Trouble",
|
||||
|
||||
# 380 - Sensor Trouble
|
||||
380 => "Sensor Trouble",
|
||||
381 => "Loss Of Supervision - RF",
|
||||
382 => "Loss Of Supervision - RPM",
|
||||
383 => "Sensor Tamper",
|
||||
384 => "RF Low Battery",
|
||||
385 => "Smoke Detector Hi Sensitivity",
|
||||
386 => "Smoke Detector Low Sensitivity",
|
||||
387 => "Intrusion Detector Hi Sensitivity",
|
||||
388 => "Intrusion Detector Low Sensitivity",
|
||||
389 => "Sensor Self-Test Failure",
|
||||
391 => "Sensor Watch Trouble",
|
||||
392 => "Drift Compensation Error",
|
||||
393 => "Maintenance Alert",
|
||||
|
||||
# 400 and 440 and 450 - Open/Close
|
||||
400 => "Open/Close",
|
||||
401 => "O/C By User",
|
||||
402 => "Group O/C",
|
||||
403 => "Automatic O/C",
|
||||
404 => "Late To O/C ",
|
||||
405 => "Deferred O/C",
|
||||
406 => "Cancel",
|
||||
407 => "Remote Arm/Disarm",
|
||||
408 => "Quick Arm",
|
||||
409 => "Keyswitch O/C",
|
||||
441 => "Armed Stay",
|
||||
442 => "Keyswitch Armed Stay",
|
||||
450 => "Exception O/C",
|
||||
451 => "Early O/C",
|
||||
452 => "Late O/C",
|
||||
453 => "Failed To Open",
|
||||
454 => "Failed To Close",
|
||||
455 => "Auto-Arm Failed",
|
||||
456 => "Partial Arm",
|
||||
457 => "Exit Error (User)",
|
||||
458 => "User On Premises",
|
||||
459 => "Recent Close",
|
||||
462 => "Legal Code Entry",
|
||||
463 => "Re-Arm After Alarm",
|
||||
464 => "Auto-Arm Time Extended",
|
||||
465 => "Panic Alarm Reset",
|
||||
466 => "Service On/Off Premises",
|
||||
|
||||
# 410 - Remote Access
|
||||
411 => "Callback Request Made",
|
||||
412 => "Successful Download/Access",
|
||||
413 => "Unsuccessful Access",
|
||||
414 => "System Shutdown Command Received",
|
||||
415 => "Dialer Shutdown Command Received",
|
||||
416 => "Successful Upload",
|
||||
|
||||
# 420 and 430 - Access Control
|
||||
421 => "Access Denied",
|
||||
422 => "Access Report By User",
|
||||
423 => "Forced Access",
|
||||
424 => "Egress Denied",
|
||||
425 => "Egress Granted",
|
||||
426 => "Access Door Propped Open",
|
||||
427 => "Access Point Door Status Monitor Trouble",
|
||||
428 => "Access Point Request To Exit Trouble",
|
||||
429 => "Access Program Mode Entry",
|
||||
430 => "Access Program Mode Exit",
|
||||
431 => "Access Threat Level Change",
|
||||
432 => "Access Relay/Trigger Fail",
|
||||
433 => "Access Rte Shunt",
|
||||
434 => "Access Dsm Shunt",
|
||||
|
||||
# 500 and 510 - System Disables
|
||||
501 => "Access Reader Disable",
|
||||
|
||||
# 520 - Sounder / Relay Disables
|
||||
520 => "Sounder/Relay Disable",
|
||||
521 => "Bell 1 Disable",
|
||||
522 => "Bell 2 Disable",
|
||||
523 => "Alarm Relay Disable",
|
||||
524 => "Trouble Relay Disable",
|
||||
525 => "Reversing Relay Disable",
|
||||
526 => "Notification Appliance Ckt. # 3 Disable",
|
||||
527 => "Notification Appliance Ckt. # 4 Disable",
|
||||
|
||||
# 530 and 540 - System Peripheral Disables
|
||||
531 => "Module Added",
|
||||
532 => "Module Removed",
|
||||
|
||||
# 550 and 560 - Communication Disables -
|
||||
551 => "Dialer Disabled",
|
||||
552 => "Radio Transmitter Disabled",
|
||||
553 => "Remote Upload/Download Disabled",
|
||||
|
||||
# 570 - Bypasses
|
||||
570 => "Zone/Sensor Bypass",
|
||||
571 => "Fire Bypass",
|
||||
572 => "24 Hour Zone Bypass",
|
||||
573 => "Burg. Bypass",
|
||||
574 => "Group Bypass",
|
||||
575 => "Swinger Bypass",
|
||||
576 => "Access Zone Shunt",
|
||||
577 => "Access Point Bypass",
|
||||
|
||||
# 600 and 610 - Test/Misc.
|
||||
601 => "Manual Trigger Test Report",
|
||||
602 => "Periodic Test Report",
|
||||
603 => "Periodic RF Transmission",
|
||||
604 => "Fire Test",
|
||||
605 => "Status Report To Follow",
|
||||
606 => "Listen-In To Follow",
|
||||
607 => "Walk Test Mode",
|
||||
608 => "Periodic Test - System Trouble Present",
|
||||
609 => "Video Xmitter Active",
|
||||
611 => "Point Tested OK",
|
||||
612 => "Point Not Tested",
|
||||
613 => "Intrusion Zone Walk Tested",
|
||||
614 => "Fire Zone Walk Tested",
|
||||
615 => "Panic Zone Walk Tested",
|
||||
616 => "Service Request",
|
||||
|
||||
# 620 - Event Log
|
||||
621 => "Event Log Reset",
|
||||
622 => "Event Log 50% Full",
|
||||
623 => "Event Log 90% Full",
|
||||
624 => "Event Log Overflow",
|
||||
625 => "Time/Date Reset",
|
||||
626 => "Time/Date Inaccurate",
|
||||
627 => "Program Mode Entry",
|
||||
628 => "Program Mode Exit",
|
||||
629 => "32 Hour Event Log Marker",
|
||||
|
||||
# 630 - Scheduling
|
||||
630 => "Schedule Change",
|
||||
631 => "Exception Schedule Change",
|
||||
632 => "Access Schedule Change",
|
||||
|
||||
# 640 - Personnel Monitoring
|
||||
641 => "Senior Watch Trouble",
|
||||
642 => "Latch-Key Supervision",
|
||||
|
||||
# 650 - Misc.
|
||||
651 => "Reserved For Ademco Use",
|
||||
652 => "Reserved For Ademco Use",
|
||||
653 => "Reserved For Ademco Use",
|
||||
654 => "System Inactivity",
|
||||
);
|
||||
|
||||
# Contact ID Event Qualifiers
|
||||
my %eventQual = (
|
||||
1 => "New Event or Opening",
|
||||
3 => "New Restore or Closing",
|
||||
6 => "Previously Reported",
|
||||
);
|
||||
|
||||
my %eventQualAlarm = (
|
||||
1 => "New",
|
||||
3 => "Restored",
|
||||
6 => "Previously Reported",
|
||||
);
|
||||
|
||||
my %eventQualOC = (
|
||||
1 => "Opening",
|
||||
3 => "Closing",
|
||||
6 => "Previously Reported",
|
||||
);
|
||||
|
||||
# Contact ID digit value map
|
||||
my %map = (
|
||||
'0' => 10,
|
||||
'1' => 1,
|
||||
'2' => 2,
|
||||
'3' => 3,
|
||||
'4' => 4,
|
||||
'5' => 5,
|
||||
'6' => 6,
|
||||
'7' => 7,
|
||||
'8' => 8,
|
||||
'9' => 9,
|
||||
'B' => 11,
|
||||
'C' => 12,
|
||||
'D' => 13,
|
||||
'E' => 14,
|
||||
'F' => 15,
|
||||
);
|
||||
my %rmap = reverse %map;
|
||||
|
||||
my $dbh = DBI->connect($dbi, $dbiUser, $dbiPassword)
|
||||
or die($DBI::errstr);
|
||||
|
||||
my $dir = IO::Dir->new($spoolDir);
|
||||
if (defined $dir) {
|
||||
while (defined($_ = $dir->read)) {
|
||||
next unless /^event/;
|
||||
print "Processing event file: $_\n";
|
||||
processEvents($_);
|
||||
}
|
||||
}
|
||||
else {
|
||||
print "Failed to open $spoolDir\n";
|
||||
}
|
||||
|
||||
$dbh->disconnect;
|
||||
|
||||
|
||||
sub processEvents {
|
||||
my $eventFile = shift;
|
||||
my $meta = 0;
|
||||
my $events = 0;
|
||||
my %metadata;
|
||||
|
||||
# delete after processing (disable for testing)
|
||||
my $deleteFile = 1;
|
||||
|
||||
# open the file
|
||||
open(my $fh, '<', "$spoolDir/$eventFile")
|
||||
or die "Could not open file '$eventFile' $!";
|
||||
|
||||
# process lines in file
|
||||
while (<$fh>) {
|
||||
next if /^\n/;
|
||||
s/\n//;
|
||||
|
||||
# file has two sections: [metadata] and [events]
|
||||
if ($_ =~ /^\[metadata\]$/) {
|
||||
print "Begin metadata...\n";
|
||||
$meta = 1;
|
||||
$events = 0;
|
||||
next;
|
||||
}
|
||||
if ($_ =~ /^\[events\]$/) {
|
||||
print "Begin events...\n";
|
||||
$meta = 0;
|
||||
$events = 1;
|
||||
next;
|
||||
}
|
||||
|
||||
if ($meta) {
|
||||
s/\r?\n$//;
|
||||
if (/([^=]+)=(.*)/) {
|
||||
$metadata{substr(lc($1), 0, 80)} = substr($2, 0, 80);
|
||||
}
|
||||
}
|
||||
|
||||
elsif ($events) {
|
||||
# Translate DTMF into Contact ID values
|
||||
s/B/E/; # DTMF B is Contact ID E
|
||||
s/C/F/; # DTMF C is Contact ID F
|
||||
s/\*/B/; # DTMF * is Contact ID B
|
||||
s/#/C/; # DTMF # is Contact ID C
|
||||
s/A/D/; # DTMF A is Contact ID D
|
||||
|
||||
# Contact ID event format
|
||||
# ACCT MT QXYZ GG CCC S
|
||||
#
|
||||
# ACCT = 4 Digit Account number (0-9, B-F)
|
||||
# MT = Message Type. either 18 (preferred) or 98 (optional)
|
||||
# Q = Event qualifier
|
||||
# XYZ = Event code (3 Hex digits 0-9,B-F)
|
||||
# GG = Group or Partition number (2 Hex digits 0-9, B-F).
|
||||
# 00 to indicate that no specific group or partition information applies.
|
||||
# CCC = Zone number (Event reports) or User # (Open / Close reports ) (3 Hex digits 0-9,B-F ).
|
||||
# 000 to indicate that no specific zone or user information applies
|
||||
# S = 1 Digit Hex checksum
|
||||
# (Sum of all message digits + S) MOD 15 = 0
|
||||
if ($_ =~ /^([0-9B-F]{4})(18|98)(1|3|6)([0-9B-F]{3})([0-9B-F]{2})([0-9B-F]{3})([0-9B-F]{1})$/) {
|
||||
|
||||
# skip if checksum failed
|
||||
if (!checksum($7)) {
|
||||
print "Skipping event $_: checksum failed!\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# skip unknown events from unknown accounts
|
||||
if (!defined($accts{$1})) {
|
||||
print "Skipping event $_: unknown account $1\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# insert event into database
|
||||
storeEvent(\%metadata, $1, $4, $_);
|
||||
|
||||
# process notifications for event
|
||||
notifyEvent(\%metadata, $1, $3, $4, $5, $6);
|
||||
|
||||
print "Account: $accts{$1}\n";
|
||||
print "Qual: $3 ".$eventQual{$3}."\n";
|
||||
print "Event: $4 ".$events{$4}."\n";
|
||||
print "Group: $5 Zone: $6\n";
|
||||
print "\n";
|
||||
|
||||
}
|
||||
else {
|
||||
print "Bad data: $_\n";
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
close $fh;
|
||||
|
||||
if ($deleteFile) {
|
||||
print "delete $spoolDir/$eventFile\n";
|
||||
unlink "$spoolDir/$eventFile";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub notifyEvent {
|
||||
my $metadata = shift;
|
||||
my $account = shift;
|
||||
my $qual = shift;
|
||||
my $event = shift;
|
||||
my $group = shift;
|
||||
my $zone = shift;
|
||||
|
||||
# don't notify for these events
|
||||
return if ($event == '602'); # routine test
|
||||
|
||||
# start with undefined message
|
||||
my $notifyString = undef;
|
||||
|
||||
# 100 series - Alarms
|
||||
if ($event =~ /1[0-9]{2}/) {
|
||||
$notifyString = sprintf("%s\nAlarm: %s \nZone: %s (%s)",
|
||||
$accts{$account}, $events{$event}, $zone, $eventQualAlarm{$qual});
|
||||
}
|
||||
|
||||
# 200 Series - Fire Supervisory
|
||||
if ($event =~ /2[0-9]{2}/) {
|
||||
$notifyString = sprintf("%s\nAlarm: %s \nZone: %s (%s)",
|
||||
$accts{$account}, $events{$event}, $zone, $eventQualAlarm{$qual});
|
||||
}
|
||||
|
||||
# 300 Series - Troubles
|
||||
if ($event =~ /3[0-9]{2}/) {
|
||||
if ($event == '350') {
|
||||
#350 => "Communication Trouble"
|
||||
$notifyString = sprintf("%s %s Line %s (%s)",
|
||||
$accts{$account}, $events{$event}, $zone, $eventQualAlarm{$qual});
|
||||
}
|
||||
elsif ($event == '354') {
|
||||
#354 => "Failure To Communicate Event"
|
||||
$notifyString = sprintf("%s %s Account %s (%s)",
|
||||
$accts{$account}, $events{$event}, $zone, $eventQualAlarm{$qual});
|
||||
}
|
||||
elsif ($zone != 000) {
|
||||
$notifyString = sprintf("%s\nAlarm: %s \nZone: %s (%s)",
|
||||
$accts{$account}, $events{$event}, $zone, $eventQualAlarm{$qual});
|
||||
}
|
||||
elsif ($group != 00) {
|
||||
$notifyString = sprintf("%s\nAlarm: %s \nModule: %s (%s)",
|
||||
$accts{$account}, $events{$event}, $group, $eventQualAlarm{$qual});
|
||||
}
|
||||
else {
|
||||
$notifyString = sprintf("%s\n%s (%s)", $accts{$account}, $events{$event}, $eventQualAlarm{$qual});
|
||||
}
|
||||
}
|
||||
|
||||
# 400 Series - Open/Close and Access
|
||||
if ($event =~ /4[0-9]{2}/) {
|
||||
if ($zone ne '000' && $group ne '00') {
|
||||
$notifyString = sprintf("%s\n%s: %s %s Partition %s", $accts{$account}, $eventQualOC{$qual}, $events{$event}, $zone, $group);
|
||||
}
|
||||
else {
|
||||
$notifyString = sprintf("%s\n%s: %s", $accts{$account}, $eventQualOC{$qual}, $events{$event});
|
||||
}
|
||||
}
|
||||
|
||||
# 601 Manual Trigger Test Report
|
||||
# 608 Periodic Test - System Trouble Present
|
||||
if ($event == '608' || $event == '601') {
|
||||
$notifyString = sprintf("%s\n%s", $accts{$account}, $events{$event});
|
||||
}
|
||||
|
||||
# append timestamp
|
||||
if (defined($notifyString)) {
|
||||
$notifyString .= "\n$$metadata{'timestamp'}";
|
||||
}
|
||||
|
||||
if (defined($notifyString)) {
|
||||
#print "NOTIFY: $notifyString\n";
|
||||
foreach (@{$notify{$account}}) {
|
||||
if (/^[0-9]{10}$/) {
|
||||
print "Notify SMS: $_\n";
|
||||
open(my $sms, '|-', "/usr/local/bin/smsclient.pl -p $_")
|
||||
or die "Could not open smsclient.pl' $!";
|
||||
print $sms $notifyString;
|
||||
close $sms;
|
||||
}
|
||||
else {
|
||||
print "Notify Email $_\n";
|
||||
my $msg = MIME::Lite->new(
|
||||
From => $emailFrom,
|
||||
To => $_,
|
||||
Subject => "Alarm Event for $accts{$account} at $$metadata{'timestamp'}",
|
||||
Type => 'text/plain; charset=utf-8',
|
||||
Data => $notifyString
|
||||
);
|
||||
$msg->add("Auto-Submitted" => "auto-generated");
|
||||
$msg->send;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# stores an event in the database
|
||||
sub storeEvent {
|
||||
my $metadata = shift;
|
||||
my $account = shift;
|
||||
my $cidevent = shift;
|
||||
my $event = shift;
|
||||
|
||||
print $$metadata{'timestamp'}."\n";
|
||||
|
||||
# parse timestamp from file metadata
|
||||
# Tue May 02, 2017 @ 21:00:01 PDT
|
||||
my $strp = DateTime::Format::Strptime->new(
|
||||
pattern => '%a %b %d, %Y @ %H:%M:%S',
|
||||
time_zone => $timezone
|
||||
);
|
||||
my $dt = $strp->parse_datetime($$metadata{'timestamp'});
|
||||
|
||||
# format timestamp for mysql
|
||||
my $timestamp = DateTime::Format::MySQL->format_datetime($dt);
|
||||
|
||||
# insert data
|
||||
$dbh->do(q{
|
||||
INSERT INTO alarmreceiver
|
||||
(timestamp, account, event, protocol, callingfrom, callername)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
},
|
||||
undef,
|
||||
$timestamp, $account, $event, $$metadata{'protocol'}, $$metadata{'callingfrom'}, $$metadata{'callername'}
|
||||
) or die($DBI::errstr);
|
||||
|
||||
# 601 Manual Trigger Test Report
|
||||
# 602 Periodic Test Report
|
||||
if ($cidevent == '602' || $cidevent == '601') {
|
||||
$dbh->do(q{
|
||||
UPDATE alarmreceiver_test
|
||||
SET timestamp = ?
|
||||
WHERE account = ?
|
||||
},
|
||||
undef,
|
||||
$timestamp, $account
|
||||
) or die($DBI::errstr);
|
||||
}
|
||||
}
|
||||
|
||||
# Contact ID Checksum
|
||||
sub checksum {
|
||||
# (Sum of all message digits + S) MOD 15 = 0
|
||||
|
||||
my $sum = 0;
|
||||
foreach my $c (split //) {
|
||||
$sum += $map{$c};
|
||||
}
|
||||
|
||||
# if result is 0, use digit F for checksum.
|
||||
if ($sum == 0) { $sum = $map{'F'}; }
|
||||
|
||||
# return 1 if checksum ok, 0 if not
|
||||
return ($sum % 15) ? 0 : 1;
|
||||
}
|
||||
30
schema/asteriskcontactid.sql
Normal file
30
schema/asteriskcontactid.sql
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
--
|
||||
-- Table structure for table `alarmreceiver`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `alarmreceiver`;
|
||||
CREATE TABLE `alarmreceiver` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`timestamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`account` smallint(5) unsigned NOT NULL,
|
||||
`event` varchar(16) NOT NULL,
|
||||
`protocol` enum('ADEMCO_CONTACT_ID') NOT NULL,
|
||||
`callingfrom` varchar(80) NOT NULL DEFAULT '',
|
||||
`callername` varchar(80) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `account` (`account`),
|
||||
KEY `callingfrom` (`callingfrom`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table structure for table `alarmreceiver_test`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `alarmreceiver_test`;
|
||||
|
||||
CREATE TABLE `alarmreceiver_test` (
|
||||
`account` smallint(5) unsigned NOT NULL,
|
||||
`test_interval` smallint(5) unsigned NOT NULL DEFAULT '24',
|
||||
`timestamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY (`account`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
Loading…
Reference in a new issue