display asterisk callerID on a squeezebox/ slimp3 using a slimserver

The goal of this small nerd activity is that my slimp3 networked mp3 players display displays the callerID of inbound calls so that I see who is calling even without looking at a phone. I have a networked slimp3 player in my living room as well as in my office.

Update: if you own a dreambox, see this article as well

prerequisites:

purpose:

Display incoming caller information on your squeezebox.

instruction:

copy the script below to a useful location (e.g. /usr/local/bin/ on a Linux system) and make it executable

$ chmod a+x /usr/local/bin/slimdisplay.pl

take a look at the scripts options

$ ./slimdisplay.pl                                                                    
usage: slimdisplay.pl <parameters>

Mandatory parameter:
--name=<player name> i.e.: "my slimp3"

Optional parameters:
--server=<ip> default: 127.0.0.1
--port=<nr> default: 9090
--line1=<text> default: "Line1 text"
--line2=<text> default: "Line2 text"
--user=<text> default: ""
--passw=<text> default: ""
--time=<nr> default: 16

test the script

slimdisplay.pl --server 192.168.20.100 --name=Wohnen --line1=Hallo --Line2="Du Da"

Add in your extension.conf for your internal number (here 2210) you would like to display the callerID info for the following line. Make sure you use the priority order (here 2).

exten => 2210,2,system(/usr/local/bin/slimdisplay.pl --name=Wohnen --line1=${CALLERIDNAME} --Line2=${CALLERIDNUM})

Call your number to test...

Bugs & Questions:

leave a comment here in the blog

#!/usr/bin/perl
# ********************************************************************
# modified by Lothar Gramelspacher
# http://blog.gramels.info/blog
# strip down to just display text messages
# renamed to slimdisplay.pl to reflect the change
# ********************************************************************
# Simple announcement script for SlimServer using the CLI v0.6
#
# Copyright (c) 2003 Felix Mueller (felix.mueller(at)gwendesign.com)
#
# This file might be distributed under the same terms as the
# SlimServer (www.slimdevices.com)
#
# Description:
# Plays a sound and shows a message interupting the current song
# - Store current parameters
# - The sound is appended to the current playlist and played
# - After the duration of the sound the sound is removed
# - Resume playing the current song
# - Restore current parameters
#
# Plattform tested:
# - Linux
# - Mac OS X 10.4 (Lothar Gramelspacher)
#
# Known restrictions:
# - trancoded files (i.e. ogg) will restart at the beginning after
# the announcement
# - a shuffled playlist will be reshuffled
# - does not work with iTunes (maybe works only with real SLIMP3)
#
# History:
# 0.6 - Added parameters for user/password (thanks to Mario Wagner)
# 0.5 - Adapted and tested with SlimServer 5.1.1
# 0.4 - Added command line parameter: --name --server --ip --line1 --line2 --sound
# - Added player selection by name
# 0.3 - Added power and volume persistency
# ********************************************************************

use strict;

use Getopt::Long;
use IO::Socket;


# Parameter defaults overridden by command line
my $szServerIP = "127.0.0.1";
my $iServerCLIPort = 9090;
my $szPlayerName = "";
my $szLine1 = "Line1 text";
my $szLine2 = "Line2 text";
my $user = "";
my $passw = "";
my $iDuration = 16;

# Internal parameters
my $debug = 0; # 0 = off, 1 = on

GetOptions( "server:s" => \$szServerIP,
"port:i" => \$iServerCLIPort,
"name:s" => \$szPlayerName,
"line1:s" => \$szLine1,
"line2:s" => \$szLine2,
"user:s" => \$user,
"passw:s" => \$passw,
"time:s" => \$iDuration);

# Check for a player name
showUsage() if( $szPlayerName eq "");

# Prepare variables
$szPlayerName = encodeChars( $szPlayerName);
$szLine1 = encodeChars( $szLine1);
$szLine2 = encodeChars( $szLine2);


# Try to open a connection to the SLIMP3 CLI
my $socket = IO::Socket::INET->new( PeerAddr => $szServerIP,
PeerPort => $iServerCLIPort,
Proto => "tcp",
Type => SOCK_STREAM);
# Check if socket was opened successful
if( !defined( $socket))
{
print "Cannot connect to $szServerIP:$iServerCLIPort\n";
exit;
}

# Login
if ($user ne "")
{
my $login = sendAndReceive("login $user $passw");
print $login;
$debug && print "user: $user, passw: $passw\n";
}

# Get the # of players
my $iNumPlayer = sendAndReceive( "player count ?");
$debug && print "iNumPlayer: $iNumPlayer\n";

# Get the player ip and port from the name
my $szPlayerIPAndPort = "";
for( my $i = 0; $i < $iNumPlayer; $i++)
{
if( $szPlayerName eq sendAndReceive( "player name $i ?"))
{
$szPlayerIPAndPort = sendAndReceive( "player address $i ?");
last;
}
}
$debug && print "szPlayerName: $szPlayerName\n";

# Check if successful
if( $szPlayerIPAndPort eq "")
{
print "Player with name: $szPlayerName could not be found!\n";
close( $socket);
exit;
}
$debug && print "szPlayerIPAndPort: $szPlayerIPAndPort\n";

# Show the announcement message
sendAndReceive( "display $szLine1 $szLine2 $iDuration");

close( $socket);

# ---------------------------------------------
sub sendAndReceive
{
my $cmd = shift;

return if( $cmd eq "");

# $cmd = $szPlayerIP . encodeChars( ":") . $iPlayerPort . " " . $cmd;

if( $szPlayerIPAndPort ne "")
{
$cmd = $szPlayerIPAndPort . " " . $cmd;
}
print $socket "$cmd\n";
my $answer = <$socket>;
$answer =~ s/$cmd //i;
$answer =~ s/\n//;

return $answer;
}

# ---------------------------------------------
sub encodeChars
{
my $myChars = $_[0];

my $MetaChars = quotemeta(' ;,/?|=+)(*&^%$#@!~`:');

$myChars =~ s/([$MetaChars\"\'\x80-\xFF])/"%" . uc( sprintf( "%2.2x", ord($1)))/eg;

return $myChars;
}

# ---------------------------------------------
sub showUsage
{
print "usage: slimdisplay.pl \n";
print "\n";
print "Mandatory parameter:\n";
print "--name=\ti.e.: \"my slimp3\"\n";
print "\n";
print "Optional parameters:\n";
print "--server=\t\tdefault: 127.0.0.1\n";
print "--port=\t\tdefault: 9090\n";
print "--line1=\t\tdefault: \"Line1 text\"\n";
print "--line2=\t\tdefault: \"Line2 text\"\n";
print "--user=\t\tdefault: \"\"\n";
print "--passw=\t\tdefault: \"\"\n";
print "--time=\t\tdefault: 16\n";
exit;
}


related blog postings:
http://dt.obility.net/index.php/disruptive-tech/asterisk-pbx/

Update: Please see Rudhom comment below for a smaller solution (no external script needed, just a line in extensions.conf). Thanks Rudhom. I will update this instruction as soon I have tested it.

Update II: I tested Rudhom's suggestion, but it seems that the wget processes stuck and create zombies.

Trackbacks

  1. display asterisk callerID on a dreambox digital TV set top box

    In addition to my recent article how to display asterisk CallerID on a Slimserver, I would like to give some instructions about how to do the same with a Dreambox (digital DVB-[T/C/S] receiver running linux) so that a incomming call will be alerted on y

  2. display asterisk callerID on a squeezebox/ slimp3 using a slimserver

    The goal of this small nerd activity is that my slimp3 networked mp3 players display displays the callerID of inbound calls so that I see who is calling even without looking at a phone. I have a networked slimp3 player in my living room as well as in my

Comments

Display comments as (Linear | Threaded)

  1. Jono says:

    Help.....please. I can get the script to run from a console but cannot get it to run on inbound calls. Using Asterisk@ home (unfortunately)

  2. gramels says:

    Hi Jono, most likely this is related to permission settings. I don't use Asterisk@home so I can not reproduce it easily. Eventually Asterisk@home uses a change rooted environment to put it in a jail in order to make it more secure. This might also prevent execution of scripts by asterisk. I would suggest to follow up on the Asterisk@home side. Please post a possible solution here.

  3. Jono says:

    Not the most elegant of solutions (mine not gramel's that is), however, with grateful thanks to gramels, I have now got this working. As I'm using asterisk@home, I had some fiddling to do: in extensions_custom.conf, somewhere near the top, I created a dummy extension number 1660 with the following: exten => 1660,1,ringing(1) exten => 1660,2,system(/usr/local/slimserver/slimdisplay.pl --name=lounge --line1=${CALLERIDNAME} --Line2=${CALLERIDNUM}) exten => 1660,3,wait(10) I found that dialling 1660 produced the desired effect on internal calls, however, if I included extension 1660 in the ring group (which falls over to an IVR after 15 seconds usually) the IVR would kick in immediately for the caller, the house phones would ring and when answered, no-one was there....and the script failed to run. So......., I created another dummy extension, however, this time, through AMP/FreePBX - ext 211. I dialled into the call forwarding system (*72) and diverted all calls for 211 to 1660. Then I included extension 211 in my ring group. Now I have caller display on my slimp3.

  4. Rudhom says:

    You can do this within extensions.conf without an external script: exten => s,1,System(/usr/bin/wget -q -b http://127.0.0.1:9000/"status?p0=display&p1=${CALLERID(num)}&p2=${CALLERID(name)}&p3=10&player=[insert player ID here]") For additional information on how these http calls work, go to "Technical Information", "Slimserver Web Interface" in your slimserver's built-in Help section.

  5. gramels says:

    Thanks Rudhom. This was what I was originally looking for, but have not found it. Much smaller that what I hacked together. I will update this instruction as soon I have tested it. -gramels

  6. Rudholm says:

    I found out after I posted that that you can use "player=*" to send the data to all connected Squeezeboxes at once. This way, you don't have to do multiple wget calls, and you don't even have to know your playerid. Also, unless you have your slimserver's "CSRF Security" set to "none", you'll have to add a ";cauth=" after the playerid. You can get this by just putting the URL in a web browser and slimserver will tell you what the cauth string should be.

  7. gramels says:

    Hi, I tested it, and it worked out for me with slight changes, see below. How ever, it seems like the wget processes create zombies. Therefore I decided to stick with my original solution with the perl script. exten => 2210,3,System(/usr/bin/wget -q -b http://127.0.0.1:9000/"status.display?p0=display&p1=${CALLERID(num)}&p2=${CALLERID(name)}&p3=10&player=*") in case you want to make the music pause onceit rings add exten => 2210,2,System(/usr/bin/wget -q -b http://127.0.0.1:9000/"status.play?p0=pause&p1=1&player=*") but make sure you put it in front of the display statement since the pause command will overwrite the display immediately. Have Fun.

  8. rudholm says:

    Hmm, I haven't had the zombie problem. I found that in some cases (depending on the version of slimserver) I had to use "status.txt" rather than just "status". I'm not sure why, since both should work.

  9. rudholm says:

    gramels, one thing you might try to avoid the zombies (and avoid leaving garbage output files in your filesystem) would be to add "-o /dev/null -O /dev/null" to the wget command options in addition to the ones you already have. This sends any output from wget, including any downloaded file, to dev/null.

  10. Rich says:

    I have used the gramels solution which appears to work ok with TB 2.3.0.1. The problem I have is that the last CLID received is being displayed on the Squeezebox at what appears to be random times, not only when I receive a call. (and thus pausing the track). It is happening perhaps every 30 seconds. I have inserted the following in extensions_additional. 600 is the ring group for all the phones which incoming calls are directed to. [ext-group] include => ext-group-custom exten => 600,1,System(/usr/bin/wget -o /dev/null -O /dev/null -q -b http://192.168.0.16:9000/"status.play?p0=pause&p1=1&player=*") exten => 600,2,System(/usr/bin/wget -o /dev/null -O /dev/null -q -b http://192.168.0.16:9000/"status.display?p0=display&p1=${CALLERID(num)}&p2=${CALLERID(name)}&p3=10&player=*") exten => 600,3,Macro(user-callerid,) Perhaps this is something to do with Asterisk 1.4 ? It it also an early beta of the TB build, so it could be that. I am just not familiar enough with the internals of TB (*) so do not know if the script is run periodically regardless of an incoming call. Regards Rich

  11. Matt Parnell says:

    Rich, I had the same problem as you, but I think I have found a solution that may help. It turns out that after making the original call to the SlimServer, wget would hang in the background, retrying indefinitely. First, try this on your machine: ps -A | grep wget This will show you if you have any wget processes hanging around. I had about 40. In my case, simply killing the processes wasn't enough, so I had to add the -9 flag: killall -9 wget Obviously use caution, as this will kill any running wget process on your system. To get to the root of the problem, I decided to run the wget at the command line as it appeared in the asterisk configuration. It hung. I removed all flags from the wget command, and got the following: "HTTP request sent, awaiting response..." It seems that the SlimServer never returns an appropriate response. So, we need to forget about hearing back from it. We don't really care what it says anyways! Looking over the wget help, two flags seem to be necessary: a timeout (-T [seconds]) and a limit on the retries (-t [tries]). By default the timeout is very long (or indefinite?) and the retries are unlimited. Set them to 0.1 seconds and 1 try. In addition, let's send the output to /dev/null as recommended by rudholm. I removed the background flag and quiet flag as I found them to be unnecessary. I also slightly modified the text to be displayed on the SqueezeBox: /usr/bin/wget -T 0.1 -t 1 -o /dev/null -O /dev/null http://127.0.0.1:9000/"status.play?p0=pause&p1=1&player=*" /usr/bin/wget -T 0.1 -t 1 -o /dev/null -O /dev/null http://127.0.0.1:9000/"status.display?p0=display&p1=Phone Number: ${CALLERID(num)}&p2=Incoming Call: ${CALLERID(name)}&p3=100&player=*" So far this has worked flawlessly - no more random pauses and persistant CID information. Let me know if it works for you. I'll test it over the next day or two and see if it holds.

  12. Dean G7PKF says:

    I cant seem to get this to work any pointers? tried both methods, the script way i can display via the command line but not from asterisk. the wget way nothing nada, any way to test/debug whats going on? using asterisk and freepbx on a clarkconnect box, squeezecenter is on the same box okay update running the cli i get this == Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'SIP/1020-08626218' -- Executing [1029@from-internal:1] Ringing("SIP/1000-08626218", "1") in new stack -- Executing [1029@from-internal:2] System("SIP/1000-08626218", "/usr/local/bin/slimdisplay.pl --name=Squeezebox --line1= --Line2=") in new stack -- Executing [1029@from-internal:3] Wait("SIP/1000-08626218", "10") in new stack == Spawn extension (from-internal, 1029, 3) exited non-zero on 'SIP/1000-08626218' this is my extension_custom.conf file exten => 1029,1,ringing(1) exten => 1029,2,system(/usr/local/bin/slimdisplay.pl --name=Squeezebox --line1=${CALLERIDNAME} --Line2=${CALLERIDNUM}) exten => 1029,3,wait(10) and the squeezebox diplays 16 for a fraction of a second, think i must have a syntax wrong any ideas?


Add Comment


HTML-Tags will be converted to Entities.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Standard emoticons like :-) and ;-) are converted to images.