He conseguido lo que quería efectuando el cambio en el archivo Predictor.class.php:
<?php
/ vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4:
Codificación: UTF-8
+----------------------------------------------------------------------+
| Issabel version 1.2-2 |
| http://www.issabel.org |
+----------------------------------------------------------------------+
| Copyright (c) 2006 Palosanto Solutions S. A. |
+----------------------------------------------------------------------+
| The contents of this file are subject to the General Public License |
| (GPL) Version 2 (the "License"); you may not use this file except in |
| compliance with the License. You may obtain a copy of the License at |
| http://www.opensource.org/licenses/gpl-license.php |
| |
| Software distributed under the License is distributed on an "AS IS" |
| basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See |
| the License for the specific language governing rights and |
| limitations under the License. |
+----------------------------------------------------------------------+
| The Initial Developer of the Original Code is PaloSanto Solutions |
+----------------------------------------------------------------------+
$Id: Predictor.class.php,v 1.5 2008/12/04 19:11:21 alex Exp $ /
define('AST_DEVICE_NOTINQUEUE', -1);
define('AST_DEVICE_UNKNOWN', 0);
define('AST_DEVICE_NOT_INUSE', 1);
define('AST_DEVICE_INUSE', 2);
define('AST_DEVICE_BUSY', 3);
define('AST_DEVICE_INVALID', 4);
define('AST_DEVICE_UNAVAILABLE',5);
define('AST_DEVICE_RINGING', 6);
define('AST_DEVICE_RINGINUSE', 7);
define('AST_DEVICE_ONHOLD', 8);
class Predictor
{
private $astConn; // Conexión al Asterisk
private $agentesAppQueue = array(); // Agentes ocupados por llamadas de cola
private $infoColas = array(); // Información de colas examinadas
private $tmp_actionid = NULL;
private $enum_complete = TRUE;
var $timestamp_examen = 0;
function __construct($astman)
{
$this->astConn = $astman;
}
function examinarColas($colas)
{
// Manejadores de eventos de interés
$this->tmp_actionid = posix_getpid().'-'.time();
$evlist = array('CoreShowChannel', 'CoreShowChannelsComplete',
'QueueParams', 'QueueMember', 'QueueEntry', 'QueueStatusComplete');
foreach ($evlist as $k)
$this->astConn->remove_event_handler($k);
foreach ($evlist as $k)
if (!$this->astConn->add_event_handler($k, array($this, "msg$k"))) {
// Quitar manejadores de eventos si alguno no se puede agregar
foreach ($evlist as $k)
$this->astConn->remove_event_handler($k);
return FALSE;
}
// Anular resultados previos
$this->agentesAppQueue = array();
$this->infoColas = array();
try {
$this->astConn->CoreShowChannels($this->tmp_actionid);
$this->esperarEnumeracion();
foreach ($colas as $queue) {
$this->astConn->QueueStatus($queue, $this->tmp_actionid);
$this->esperarEnumeracion();
}
} catch (Exception $e) {
// Quitar manejadores de eventos antes de relanzar excepción
foreach ($evlist as $k)
$this->astConn->remove_event_handler($k);
throw $e;
}
// Quitar manejadores de eventos
foreach ($evlist as $k)
$this->astConn->remove_event_handler($k);
$this->tmp_actionid = NULL;
$this->timestamp_examen = microtime(TRUE);
return TRUE;
}
private function esperarEnumeracion()
{
$this->enum_complete = FALSE;
do {
if ($this->astConn->multiplexSrv->procesarPaquetes())
$this->astConn->multiplexSrv->procesarActividad(0);
else $this->astConn->multiplexSrv->procesarActividad(1);
} while (!$this->enum_complete);
}
function msg_CoreShowChannel($sEvent, $params, $sServer, $iPort)
{
if (is_null($this->tmp_actionid)) return;
if ($params['ActionID'] != $this->tmp_actionid) return;
/
Event: CoreShowChannel
ActionID: gatito
Channel: SIP/1064-00000003
UniqueID: 1441991140.4
Context: from-internal
Extension: 8001
Priority: 1
ChannelState: 6
ChannelStateDesc: Up
Application: AppQueue
ApplicationData: (Outgoing Line)
CallerIDnum: 1064
CallerIDname: Alex
ConnectedLineNum: 1071
ConnectedLineName: A Cuenta SIP
Duration: 00:09:46
AccountCode:
BridgedChannel: SIP/1071-00000002
BridgedUniqueID: 1441991139.3
/
if ($params['ChannelState'] != 6) return;
if ($params['Application'] != 'AppQueue') return;
if (!isset($params['BridgedChannel']) || trim($params['BridgedChannel']) == '') return;
$regs = NULL; $interface = NULL;
$regex = '#([[:alnum:]-]+/.+?)(-[\dabcdef]+((,|(1|2))?)?$#';
if (is_null($interface) && preg_match($regex, $params['Channel'], $regs)) {
$interface = $regs[1];
$timefields = explode(':', $params['Duration']);
$this->agentesAppQueue[$interface] = (int)$timefields[0] 3600 + (int)$timefields[1] 60 + (int)$timefields[2];
}
}
function msg_CoreShowChannelsComplete($sEvent, $params, $sServer, $iPort)
{
if (is_null($this->tmp_actionid)) return;
if ($params['ActionID'] != $this->tmp_actionid) return;
$this->enum_complete = TRUE;
}
function msg_QueueParams($sEvent, $params, $sServer, $iPort)
{
if (is_null($this->tmp_actionid)) return;
if ($params['ActionID'] != $this->tmp_actionid) return;
if (!isset($this->infoColas[$params['Queue']])) {
$this->infoColas[$params['Queue']] = array(
'members' => array(),
'callers' => 0,
);
}
}
function msg_QueueMember($sEvent, $params, $sServer, $iPort)
{
if (is_null($this->tmp_actionid)) return;
if ($params['ActionID'] != $this->tmp_actionid) return;
$this->infoColas[$params['Queue']]['members'][$params['Location']] = array(
//'Name' => $params['Name'],
//'Location' => $params['Location'],
//'StateInterface' => $params['StateInterface'],
'Paused' => ($params['Paused'] != 0),
'Status' => (int)$params['Status'],
);
}
function msg_QueueEntry($sEvent, $params, $sServer, $iPort)
{
if (is_null($this->tmp_actionid)) return;
if ($params['ActionID'] != $this->tmp_actionid) return;
if (!isset($this->infoColas[$params['Queue']]['callers']))
$this->infoColas[$params['Queue']]['callers'] = 0;
$this->infoColas[$params['Queue']]['callers']++;
}
function msg_QueueStatusComplete($sEvent, $params, $sServer, $iPort)
{
if (is_null($this->tmp_actionid)) return;
if ($params['ActionID'] != $this->tmp_actionid) return;
$this->enum_complete = TRUE;
}
function infoPrediccionCola($cola)
{
if (!isset($this->infoColas[$cola])) return NULL;
$iNumLlamadasColocar = array(
'AGENTES_LIBRES' => 0,
'AGENTES_POR_DESOCUPAR' => array(),
'CLIENTES_ESPERA' => 0,
);
$iNumLlamadasColocar['CLIENTES_ESPERA'] = $this->infoColas[$cola]['callers'];
foreach ($this->infoColas[$cola]['members'] as $interface => $miembro) {
// Se ignora miembro en pausa
if ($miembro['Paused']) continue;
// Miembro definitivamente libre
if (in_array($miembro['Status'], array(AST_DEVICE_NOT_INUSE, AST_DEVICE_RINGING)))
$iNumLlamadasColocar['AGENTES_LIBRES'] = $n=$n+5;
// Miembro ocupado, se verifica si se desocupará
if (in_array($miembro['Status'], array(AST_DEVICE_INUSE, AST_DEVICE_BUSY, AST_DEVICE_RINGINUSE)) &&
isset($this->agentesAppQueue[$interface])) {
$iNumLlamadasColocar['AGENTES_POR_DESOCUPAR'][] = $this->agentesAppQueue[$interface];
}
}
return $iNumLlamadasColocar;
}
function predecirNumeroLlamadas($infoCola, $prob_atencion = NULL, $avg_duracion = NULL, $avg_contestar = NULL)
{
$n = 0;
// Miembro ocupado, se verifica si se desocupará
if (!is_null($prob_atencion)) foreach ($infoCola['AGENTES_POR_DESOCUPAR'] as $t) {
$iTiempoTotal = $avg_contestar + $t;
// Probabilidad de que 1 llamada haya terminado al cabo de $iTiempoTotal s.
$iProbabilidad = $this->probabilidadErlangAcumulada(
$iTiempoTotal,
1,
1 / $avg_duracion);
if ($iProbabilidad >= $prob_atencion) $n++;
}
$infoCola['AGENTES_POR_DESOCUPAR'] = $n;
return $infoCola;
}
private function probabilidadErlangAcumulada($x, $k, $lambda)
{
$iSum = 0;
$iTerm = 1;
for ($n = 0; $n < $k; $n++) {
if ($n > 0) $iTerm = $lambda $x / $n;
$iSum += $iTerm;
}
return 1 - exp(-$lambda $x) $iSum;
}
}
?>