Write to Display on a Cisco 7960?
I have, for a necessary need, multiples queues. To make it easy on my staff, they hit a button on their phone, it dials the QUEUE Login code, and boom, it auto-logs them into ALL queues... the same with the logout button. Neat. Works great.
My question is THIS - I have Cisco 7960's phones. Is there ANY way I can write something to the phone (like a word on it's graphic display) to show they're logged into the queue? A Code I can add to this script somehow? Maybe even update the logo graphic if I had to? Anything?
Here's my neat auto-queue login script with comments:
### START OF CODE - GOES IN extensions-custom.conf
; Log On/Off to All Main Queues (It Toggles)
exten => 9990*,1,Wait(1)
exten => 9990*,n,Macro(agent-manage-full,900,)
exten => 9990*,n,Hangup()
; Log On/Off to Tech but not Billing Queues (It Toggles)
exten => 9991*,1,Wait(1)
exten => 9991*,n,Macro(agent-manage-techonly,900,)
exten => 9991*,n,Hangup()
; Log On/Off to Badging Queue (It Toggles)
exten => 9995*,1,Wait(1)
exten => 9995*,n,Macro(agent-manage,925,) ;
exten => 9995*,n,Hangup()
; Adds or removes a dynamic agent/member for a queue
; arg1 = queue number, arg2 = number
[macro-agent-manage]
exten => s,1,Wait(1)
exten => s,2,Macro(user-callerid)
exten => s,3,Set(CALLBACKNUM=${CALLERID(number)})
exten => s,4,GotoIf($["${CALLBACKNUM}" = ""]?111)) ; if no number, jump to fail.
exten => s,5,AddQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n||j) ; using chan_local allows us to have agents over trunks
exten => s,6,UserEvent(Agentlogin|Agent: ${CALLBACKNUM})
exten => s,7,Wait(1)
exten => s,8,Playback(agent-loginok)
exten => s,9,Hangup()
exten => s,106,RemoveQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n)
exten => s,107,UserEvent(RefreshQueue)
exten => s,108,Wait(1)
exten => s,109,Playback(agent-loggedoff)
exten => s,110,Hangup()
exten => s,111,Playback(sorry-cant-let-you-do-that) ; Catch error and give simple notification.
exten => s,112,Hangup()
[macro-agent-manage-full]
exten => s,1,Wait(1)
exten => s,2,Macro(user-callerid)
exten => s,3,Set(CALLBACKNUM=${CALLERID(number)})
exten => s,4,GotoIf($["${CALLBACKNUM}" = ""]?119)) ; if no number, jump to fail.
exten => s,5,AddQueueMember(900|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,6,AddQueueMember(901|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,7,AddQueueMember(902|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,8,AddQueueMember(903|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,9,AddQueueMember(904|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,10,AddQueueMember(905|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,11,AddQueueMember(906|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,12,AddQueueMember(907|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,13,AddQueueMember(908|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,14,UserEvent(Agentlogin|Agent: ${CALLBACKNUM})
exten => s,15,Wait(1)
exten => s,16,Playback(agent-loginok)
exten => s,17,Hangup()
exten => s,106,RemoveQueueMember(900|Local/${CALLBACKNUM}@from-internal/n)
exten => s,107,RemoveQueueMember(901|Local/${CALLBACKNUM}@from-internal/n)
exten => s,108,RemoveQueueMember(902|Local/${CALLBACKNUM}@from-internal/n)
exten => s,109,RemoveQueueMember(903|Local/${CALLBACKNUM}@from-internal/n)
exten => s,110,RemoveQueueMember(904|Local/${CALLBACKNUM}@from-internal/n)
exten => s,111,RemoveQueueMember(905|Local/${CALLBACKNUM}@from-internal/n)
exten => s,112,RemoveQueueMember(906|Local/${CALLBACKNUM}@from-internal/n)
exten => s,113,RemoveQueueMember(907|Local/${CALLBACKNUM}@from-internal/n)
exten => s,114,RemoveQueueMember(908|Local/${CALLBACKNUM}@from-internal/n)
exten => s,115,UserEvent(RefreshQueue)
exten => s,116,Wait(1)
exten => s,117,Playback(agent-loggedoff)
exten => s,118,Hangup()
exten => s,119,Playback(sorry-cant-let-you-do-that) ; Catch error and give simple notification.
exten => s,120,Hangup()
[macro-agent-manage-techonly]
exten => s,1,Wait(1)
exten => s,2,Macro(user-callerid)
exten => s,3,Set(CALLBACKNUM=${CALLERID(number)})
exten => s,4,GotoIf($["${CALLBACKNUM}" = ""]?117)) ; if no number, jump to fail.
exten => s,5,AddQueueMember(900|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,6,AddQueueMember(901|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,7,AddQueueMember(903|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,8,AddQueueMember(904|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,9,AddQueueMember(906|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,10,AddQueueMember(907|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,11,AddQueueMember(908|Local/${CALLBACKNUM}@from-internal/n||j)
exten => s,12,UserEvent(Agentlogin|Agent: ${CALLBACKNUM})
exten => s,13,Wait(1)
exten => s,14,Playback(agent-loginok)
exten => s,15,Hangup()
exten => s,106,RemoveQueueMember(900|Local/${CALLBACKNUM}@from-internal/n)
exten => s,107,RemoveQueueMember(901|Local/${CALLBACKNUM}@from-internal/n)
exten => s,108,RemoveQueueMember(903|Local/${CALLBACKNUM}@from-internal/n)
exten => s,119,RemoveQueueMember(904|Local/${CALLBACKNUM}@from-internal/n)
exten => s,110,RemoveQueueMember(906|Local/${CALLBACKNUM}@from-internal/n)
exten => s,111,RemoveQueueMember(907|Local/${CALLBACKNUM}@from-internal/n)
exten => s,112,RemoveQueueMember(908|Local/${CALLBACKNUM}@from-internal/n)
exten => s,113,UserEvent(RefreshQueue)
exten => s,114,Wait(1)
exten => s,115,Playback(agent-loggedoff)
exten => s,116,Hangup()
exten => s,117,Playback(sorry-cant-let-you-do-that) ; Catch error and give simple notification.
exten => s,118,Hangup()
I don't think it's possible to update the display, but I patched together a php file that will display QueueStatus in Cisco XML Services format - it will list the extension and display name of what phones are logged into the queues. It does an AMI request, grabs the extensions, looks up the name in MySQL (in this case SugarCRM, but you can easily changed it to the FreePBX database), and then spits it out in XML.
You'll need to adjust the variables to work for you, especially the $pattern. I changed the login information to use the defaults, but I created AMI and MySQL accounts just for this purpose.
<?php
// PHP script to retrieve Asterisk Management Interface (AMI) information - grab extensions via AMI and name from MySQL by looking up extension - and then output in Cisco XML Services format
// 04-28-08 - Initial version - Josh Reineke
// AMI
$amihost = 'localhost';
$amiuser = 'admin';
$amipass = 'amp111';
$amicommand = 'QueueStatus';
// MySQL
$dbhost = 'localhost';
$dbuser = 'sugarcrm';
$dbpass = 'sugarcrm';
$dbname = 'sugarcrm';
// RegEx pattern
$pattern="61..";
// XML
$xmltitle="Queue Status";
$xmlprompt="Queue Status";
// connect to AMI
$timeout = 7500;
$socket = fsockopen("$amihost","5038", $errno, $errstr, $timeout);
fputs($socket, "Action: Login\r\n");
fputs($socket, "UserName: $amiuser\r\n");
fputs($socket, "Secret: $amipass\r\n\r\n");
fputs($socket, "Action: $amicommand\r\n\r\n");
fputs($socket, "Action: Logoff\r\n\r\n");
while (!feof($socket)) {
$amioutput .= fread($socket, 8192);
}
fclose($socket);
// perform RegEx on AMI output to grab information
preg_match_all("/$pattern/", $amioutput, $matches);
// grab "real" array out of the first dimension of the array created by preg_match_all
$data = $matches[0];
// sort array by value - ascending
asort($data);
// remove duplicates from array
$extensions = array_unique($data);
// connect to MySQL
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql');
mysql_select_db($dbname);
// output XML file in format Cisco IP phone can read
header('Content-type: text/xml');
$menu = "
$menu .= "
$menu .= "
$menu .= "
foreach ($extensions as $value) {
$extension = $value;
$query = "SELECT first_name, last_name FROM users WHERE phone_work = $extension";
$results = mysql_query($query);
while($row = mysql_fetch_array($results, MYSQL_ASSOC)) {
$first_name = $row['first_name'];
$last_name = $row['last_name'];
}
$menu .= "$extension - $first_name $last_name\n";
}
$menu .= "
\n";$menu .= "\n";
echo $menu;
mysql_close($conn);
?>
Actually you can update the display on the phone, it's called the CiscoIPPhoneStatus and CiscoIPPhoneStatusFile commands. By default the Cisco endpoint manager sets the phones up to talk to a /cisco/services/authentication.php page to authenticate for push to phone services, however that file is not created by default. What you would want to do is have your login number call an AGI script which sends the CiscoIPPhoneExecute command to show the CiscoIPPhoneStatus page.
Check out the link below and some sample code to get you started:
http://www.cisco.com/en/US/docs/voice_ip_comm/cuipph/all_models/x...
Sample PHP page:
<?php
# Set content type
header("Content-Type: text/xml");
$menu .= "<CiscoIPPhoneStatusFile>";
$menu .= "<Text>Title value</Text>";
$menu .= "<Timer>Timer value</Timer>";
$menu .= "<LocationX>Horizontal Offset</LocationX>";
$menu .= "<LocationY>Vertical Offset</LocationY>";
$menu .= "<URL>LOCATION OF PNG IMAGE</URL>";
$menu .= "</CiscoIPPhoneStatusFile>";
echo $menu;
?>
Sample push to phone PHP:
<?php
function push2phone($ip, $uri, $uid, $pwd)
{
$auth = base64_encode($uid.":".$pwd);
$xml = "<CiscoIPPhoneExecute><ExecuteItem Priority=\"0\"URL=\"".$uri."\"/></CiscoIPPhoneExecute>";
$xml = "XML=".urlencode($xml);
$post = "POST /CGI/Execute HTTP/1.0\r\n";
$post .= "Host: $ip\r\n";
$post .= "Authorization: Basic $auth\r\n";
$post .= "Connection: close\r\n";
$post .= "Content-Type: application/x-www-form-urlencoded\r\n";
$post .= "Content-Length: ".strlen($xml)."\r\n\r\n";
$fp = fsockopen ( $ip, 80, $errno, $errstr, 30);
if(!$fp){ echo "$errstr ($errno)<br>\n"; }
else
{
fputs($fp, $post.$xml);
flush();
while (!feof($fp))
{
$response .= fgets($fp, 128);
flush();
}
}
return $response;
}
$ip = "192.168.10.201";
$uri = "http://192.168.10.20/cisco/services/info.php";
//$uri = "Dial:1022";
$uid = "admin";
$pwd = "Cisco";
echo push2phone($ip, $uri, $uid, $pwd);
?>
/cisco/services/authentication.php
<?php echo "AUTHORIZED"; ?>
If you need more help let me know and we can work something out.
EDIT:
I should note this is for a 7970, for a 7960 you need to use the CiscoIPPhoneStatus and convert an image to CIP

Member Since:
2007-12-11