There are times when it may be useful to have a visible indication that the phones are ringing, or a message has been left. For example:
Hearing impairment
In this article we show how to integrate an EggNunciator or Sentinel that is already monitoring home conditions with the Asterisk VOIP soft exchange.
First, lets look at the extensions.conf file for the extension we wish to Eggnunciate:
exten => 1000,1,agi,Ringing2.py
exten => 1000,2,Dial(SIP/phonexeon,20,tr)
exten => 1000,3,goto,1
This fragment shows us that the first operation to be performed when extension 1000 is called is to run the AGI program Ringing2.py. As soon as that program has completed, the phone (SIP/phonexeon,20,tr) is tried, the timeout is 20 seconds, after this, the goto,1 takes us back to the Ringing2.py AGI Program. This will continue until the call is answered, or the caller hangs-up. Here is the source of Ringing2.py:
!/usr/bin/python
#==========================================================
# More complex example of 'Ringing'
# In this case, we try to work out
# if the phone has been answered
#==========================================================
#
#
#
#
from socket import socket, AF_INET, SOCK_DGRAM
import agi
if __name__ == '__main__':
agiInst = agi.agi()
Ringing = 1
ServerIP = '10.2.0.8'
ThePort = 2553
FrameData = 'Ringing'
f = open ("/var/lib/asterisk/agi-bin/trace.log", "a")
f.write(" ============== I was called =================
")
for key in agiInst.env:
f.write(key)
f.write(" ")
f.write(agiInst.env[key])
f.write("
")
try:
while Ringing:
hbsocket = socket(AF_INET, SOCK_DGRAM)
hbsocket.sendto(FrameData, (ServerIP, ThePort))
if agiInst.env["agi_channel"]:
f.write("Checking channel status
")
cmdstr = "CHANNEL STATUS " + agiInst.env["agi_channel"]
result = agiInst.cmd(cmdstr)
f.write ("Channel Status : %s
" % str(result))
if str(result[1]) == "4":
Ringing = 0
except:
f.write("Problem in channel state testing
")
f.close()
This code generates a UDP packet that is sent to the host:port 10.2.0.8:2553 at this host:port we are running a multi-threaded version of the EggNunciator code. Here's a fragment of the UDP thread:
def UDPRecv():
global doUDP
GlobCount = 0
recvport = 2553
tim = time.strftime("%d %b %Y %H:%M:%S", time.gmtime())
print "UDP Thread started ", tim, " Recieving on port ", recvport
s = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
s.bind(('', recvport))
s.setsockopt( socket.SOL_SOCKET, socket.SO_BROADCAST, 1 )
try:
while 1:
(data,addr) = s.recvfrom( 100 )
doUDP = 5 # we found a packet, cycle this many times
GlobCount = GlobCount + 1
tim = time.strftime("%d %b %Y %H:%M:%S", time.gmtime())
OutStr = "<event><no>" + str(GlobCount) + "</no><time>" + tim + "</time><address>" + addr[0] + "</address><data>"
for count in range(len(data)):
OutStr = OutStr + str(ord(data[count])) + " "
OutStr = OutStr + "</data></event>"
if debug: print OutStr
except KeyboardInterrupt:
print "Closing UDP Recv"
s.close()
So you can see that each time a packet is received the EggNunciator will make 5 cycles of the Ringing 'scene'. The behaviour of the EggNunciator is set in an XML file, here is an example: <?xml version="1.0"?>
<configuration>
<IP>10.100.100.101</IP>
<steps>128</steps>
<aLevel>32</aLevel>
<qLevel>24</qLevel>
<conditions>Ringing,GarageDoorsA,GarageDoorsB,ColdOutside</conditions>
<Ringing>any,UDP,any,00.128.00</Ringing>
<GarageDoorsA>10.0.0.25,MonStatus,10,128.00.00</GarageDoorsA>
<GarageDoorsB>10.0.0.26,MonStatus,10,128.00.00</GarageDoorsB>
<ColdOutside>10.0.0.19,OWRes,5,00.00.128</ColdOutside>
</configuration>
From this you can see that the scene definition for 'Ringing' is 0.128.0 or full Green.