Simple Alarm call center script. This script can by used as after script for Asterisk AlarmReceiver cmd.
This script read saved events from asterisk alarm receiver. If the event is important (Alarm event) script create
asterisk call file which make a call and play sound message to selected numbers.
You can also receive formated events to email.
Notes:
For better results in communication you can try increase output gain on your ATA (default setting is -3)
FXS Port Output Gain: +1
You must set all other regional settings to match your alarm !!! (FXS Port Impedance, Ring Frequency, Ring Voltage, ...)
Other info for Asterisk AlarmReceiver cmd can be found here:
http://www.voip-info.org/wiki/index.php?page=Asterisk+cmd+AlarmReceiver
Written by
Uroš Indihar
Alphito d.o.o.
Changelog
0.1 Initial release
0.2 1.12.1008
Added mail support
License GNU GPL3.
Warranty: None. Use at your own risk !
Example: alarmreceiver.conf
[general]
timestampformat = %a %b %d, %Y @ %H:%M:%S %Z
eventcmd = /usr/local/bin/after_alarm_event.php
eventspooldir = /var/spool/asterisk/alarm_events
logindividualevents = yes
fdtimeout = 2000
sdtimeout = 200
loudness = 8192
------------------------------------------------------------------------------------------------
Example: sip.conf (pstn to sip part)
[31]
type=friend
context=phones
host=dynamic
secret=*******
callerid="Ademco Alarm" <31>
dtmfmode=inband
disallow=all
allow=ulaw
------------------------------------------------------------------------------------------------
Example: extension.conf
[internal]
;alarm receiver
exten => 560,1,Verbose(1|Extension 560 - Alarm Receiver)
exten => 560,n,Ringing()
exten => 560,n,Wait(2)
exten => 560,n,AlarmReceiver()
exten => 560,n,Hangup()
[alarmreport]
exten => start,1,Answer()
exten => start,n,Wait(1)
exten => start,n,Playback(ha/alarm)
exten => start,n,Wait(1)
exten => start,n,Playback(ha/alarm)
exten => start,n,Wait(1)
exten => start,n,Playback(ha/alarm)
exten => start,n,Wait(1)
exten => start,n,Playback(ha/alarm)
exten => start,n,Wait(1)
exten => start,n,Playback(ha/alarm)
exten => start,n,Wait(1)
exten => start,n,Playback(ha/alarm)
exten => start,n,Wait(1)
exten => start,n,Playback(ha/alarm)
exten => start,n,Wait(1)
exten => start,n,Playback(vm-goodbye)
exten => start,n,Hangup()
#!/usr/bin/php -q
<?php
class ademcoEventParser {
var $eventMap=array(
110 => "Fire Alarm",
121 => "Duress",
122 => "Alarm, 24-hour Silent",
123 => "Alarm, 24-hour Audible",
131 => "Alarm, Perimeter",
132 => "Alarm, Interior",
134 => "Alarm, Entry/Exit",
135 => "Alarm, Day/Night",
143 => "Alarm, Expansion Module",
146 => "Silent Burglary",
150 => "Alarm, 24-Hour Auxiliary",
301 => "AC Power",
302 => "Low System Battery/Battery Test Fail",
305 => "System Reset",
333 => "Trouble or Tamper Expansion Module",
351 => "Telco Line Fault",
353 => "Long Range Radio Trouble",
373 => "Fire Loop Trouble",
374 => "Exit Error Alarm",
380 => "Global Trouble, Trouble Day/Night",
381 => "RF Supervision Trouble",
383 => "RF Sensor Tamper",
384 => "RF Sensor Low Battery",
401 => "Disarmed, Armed AWAY (MAX), Armed AWAY",
406 => "Cancel by User",
407 => "Remote Arm/Disarm (Downloading)",
408 => "Quick Arm AWAY/MAX",
441 => "Disarmed/Armed STAY/INSTANT , Quick Arm STAY/INSTANT",
570 => "Bypass",
602 => "Periodic Test",
606 => "AAV to follow",
607 => "System Test",
623 => "Event Log 80% Full",
629 => "1-1/3 Day No Event",
);
var $eventsDir="/var/spool/asterisk/alarm_events/";
var $eventPrefix="event-";
var $lastEventSave="last_received_event";
var $actionChannels=array( //ademco_id => array(channel1,channel2,...);
"NNNN(ADEMCO_ID 1)"=>array(
"SIP/NNNNNN (Asterisk channel)",
"SIP/NNNNNN (Asterisk channel)",
),
"NNNN(ADEMCO_ID 2)"=>array(
"SIP/NNNNNN (Asterisk channel)",
),
);
var $callFileDir="/var/spool/asterisk/outgoing/";
var $actionChannelsMail=array( //ademco_id => array(Email1=>Name1,Email2=>Name2,...);
"NNNN(ADEMCO_ID 1)"=>array(
"example@example.com"=>"My Name",
"example1@example.com"=>"My Name1",
),
"NNNN(ADEMCO_ID 2)"=>array(
"example@example.com"=>"My Name",
),
);
var $emailFromName="Ademco Alarm Report";
var $emailFrom="cron@alphito.si";
var $callerId="Alarm Report <NNNNNNNNNNNN>";
function setEventsDir($dir) {
$this->eventsDir=$dir;
}
function getEventFiles() {
$eventFiles=array();
$eventPrefixLen=strlen($this->eventPrefix);
$dh = opendir($this->eventsDir);
while (($file = readdir($dh)) !== false) {
if (substr($file,0,$eventPrefixLen) == $this->eventPrefix) {
$eventFiles[$file]=filemtime($this->eventsDir.$file);
}
}
asort($eventFiles);
closedir($dh);
$this->eventFiles=$eventFiles;
}
function loop() {
foreach ($this->eventFiles as $file => $mtime) {
$data=$this->parse($file);
foreach ($data["events"] as $event) {
//echo $event;
$e=$this->parseEvent($event);
if ($this->getSavedEvent() == $event) {
//event is duplicated to last event
$this->log($data["metadata"],$event,"Duplicated event",$e);
} else {
$this->saveEvent($event);
$this->log($data["metadata"],$event,"New event",$e);
$this->action($e,$data["metadata"],$event);
}
}
//print_r($data);
//remove file
unlink($this->eventsDir.$file);
}
}
function action($e,$metadata,$event) {
if(intval($e["e"]) < 200) {
//do action on alarm events
$this->log($metadata,$event,"Starting action",$e);
foreach ($this->actionChannels[$e["id"]] as $callChannel) {
$this->createCallFile($callChannel);
}
}
//send email report
if (is_array($this->actionChannelsMail[$e["id"]])) {
$msg ="Ademco alarm report.\n\n";
$msg.="Logged event at ".date("d.m.Y H:i:s",time()).".\n\n";
$msg."Event data:\n\n";
$msg.=implode(", ",$metadata)."\n";
$msg.=$event."\n";
$msg.=implode(", ",$e)."\n";
$msg.=$this->eventMap[$e["e"]]."\n\n";
$subject ="[ ALARM ] ".$this->eventMap[$e["e"]];
foreach ($this->actionChannelsMail[$e["id"]] as $email => $name) {
$this->sendMail($subject,$name,$email,$this->emailFromName,$this->emailFrom,$msg);
}
}
}
function createCallFile($channel) {
$callFile ="Channel: ".$channel."\n";
$callFile.="CallerID: ".$this->callerId."\n";
$callFile.="MaxRetries: 10\n";
$callFile.="RetryTime: 60\n";
$callFile.="WaitTime: 30\n";
$callFile.="Context: alarmreport\n";
$callFile.="Extension: start\n";
$callFile.="Priority: 1\n";
file_put_contents($this->callFileDir.uniqid("alarm").".call",$callFile);
}
function getSavedEvent () {
$lastEvent=@file_get_contents($this->eventsDir.$this->lastEventSave);
return $lastEvent;
}
function saveEvent($event) {
file_put_contents($this->eventsDir.$this->lastEventSave,$event);
}
function parseEvent($event) {
$e=array(
"id" => substr($event,0,4),
"q" => substr($event,4,3),
"e" => substr($event,7,3),
"z" => substr($event,10),
);
//print_r($e);
return($e);
}
function log($metadata,$event,$string,$e) {
syslog(LOG_NOTICE,implode(", ",$metadata).", ".$event.", ".$string.", ".implode(", ",$e).", ".$this->eventMap[$e["e"]]);
}
function parse($file) {
$fp=fopen($this->eventsDir.$file,"r");
$section="";
$data=array();
while (!feof($fp)) {
$line = trim(fgets($fp,4096));
if (substr($line,0,1) == "[") {
//new section started
$section=substr($line,1,-1);
$data[$section]=array();
} elseif (strlen($section) > 0) {
//we are in section
switch ($section) {
case "metadata":
if (strlen($line) > 0) {
//dont include empty lines
list($key,$val)=explode("=",$line);
//echo $key."->".$val."\n";
$data[$section][trim($key)]=trim($val);
}
break;
case "events":
if (strlen($line) > 0) {
$data[$section][]=trim($line);
}
break;
}
}
//echo $line."\n";
}
fclose($fp);
return $data;
}
function sendMail($subject,$tostr,$toemail,$fromstr,$fromemail,$msg) {
$from = '"';
$from.=$this->encode($fromstr);
$from.= '"';
$from.="<".$fromemail.">";
$to = '"';
$to.=$this->encode($tostr);
$to.= '"';
$to.="<".$toemail.">";
//$msubject=$this->encode($subject);
$msubject=$subject;
$headers = "MIME-Version: 1.0\n";
$headers .= "Content-type: text/plain; charset=utf-8\n";
$headers .= "From: ".$from."\n";
return mail($to, $msubject, $msg, $headers);
}
function encode($in_str, $charset="UTF-8") {
$out_str = $in_str;
if ($out_str && $charset) {
$end = "?=";
$start = "=?" . $charset . "?B?";
$spacer = $end . "\n " . $start;
$length = 75 - strlen($start) - strlen($end);
$length = floor($length/2) * 2;
$out_str = base64_encode($out_str);
$out_str = chunk_split($out_str, $length, $spacer);
$spacer = preg_quote($spacer);
$out_str = preg_replace("/" . $spacer . "$/", "", $out_str);
$out_str = $start . $out_str . $end;
}
return $out_str;
}
}
$aep=new ademcoEventParser();
$aep->getEventFiles();
$aep->loop();
?>