fibaro domotica razberry z-wave

Razberry: Domotica low-cost existe gracias a Z-Wave

Es curioso porque cuando compré mi placa Razberry Z-Wave tenía ciertas dudas si conseguiría que funcionase algo con todo esto de la Domotica. Como comentaba en el anterior artículo, todo mi interés surgió cuando me dispuse a investigar sobre soluciones de Smart Metering y vi que los productos completos en el mercado eran excesivamente caros para mi gusto. De pronto, me encontré con los Fibaro Wall-Plugs: Ese tipo de medidores que llaman a la vista por ser excepcionalmente pequeños, y que al parecer, cumplían el objetivo! Con eso solo faltaba el controlador Z-Wave, y por menos de 200 euros, bastante difícil bajarse del burro: Hasta que localice el Razberry Z-Wave 2 por 1: Una interfaz con una API REST y realizaba la función al milímetro. Pero como suelen decir: las gangas no existen, y necesitaba comprobarlo con mis propios ojos, así que hice el pedido (que por cierto, sorprendentemente llego en poco más de un día a través de la tienda online zwave.es y yo esperaba que esa tarjeta Razberry tardará semanas, o incluso meses por ser relativa como popular). Y con todo el material en casa, me dispuse a montar el sistema

fibaro domotica razberry z-wave

Primero el objetivo: Saber cuánto consumen los distintos dispositivos eléctricos/electrónica de mi casa. Quizá en un futuro gracias a la domotica, sería interesante tener una gráfica de consumo y tal, pero creo que es sería más interesante con un dispositivo que se coloca en el cuadro general y mide el consumo general de toda la casa. Pero para un dispositivo en concreto creo que realmente la gracia está en saber cuánto consume.

Por ejemplo: Ponemos el controlador en la lavadora, ponemos el programa clásico de lavado y podemos observar cuanto ha consumido (a pesar de las especificaciones del fabricante). Ahora mismo estoy comprobando el consumo de los emisores térmicos de mi casa, que tienen fama de “ahorro energético” pero tengo la sensación que no es cierto del todo. Esta es una de las bondades de la domotica.

Configurando la interfaz Domotica del Razberry en nuestra Raspberry Pi

Ahora manos a la obra. En primer lugar vamos a configurar el sistema. Para ello nos hace falta tener una Raspberry Pi a la que conectar la placa Razberry Z-Wave (encima de los 10-pines más pegados a la ranura de la tarjeta SD, aunque una imagen vale más que mil palabras)

raspberry pi z-wave razberry domotica

Si ya tenemos Rasbian instalado (versión wheezy en el momento de escribir este artículo más convenientemente), simplemente tendremos que ejecutar el siguiente comando:

wget -q -O - razberry.z-wave.me/install | sudo bash

Con esto quedan instalados los drivers para la Razberry, y el software al que se accede vía web. Quizá necesario reiniciar el sistema para que el sistema operativo reconozca la tarjeta una vez instalado el driver. A partir de aquí ya podemos acceder a la interfaz web:

http://ip_raspberry_pi:8083/expert/

Ahora tenemos que configurar nuestro Fibaro Wall Plug en el sistema de domotica Razberry Z-Wave. Para ello simplemente conectamos el Wall-Plug al dispositivo eléctrico y la corriente como es lógico, y debería encenderse ya el LED en un color indicando el consumo del dispositivo en cuestión (si está apagado, lo más probable es que los leds estén en un azul muy claro). Simplemente con esta acción, el Fibaro Wall-Plug estará preparado para sincronizar con nuestro Razberry. Para ello desde la interfaz web vamos a Network -> Network Management -> (Re)include device y si todo va bien, debería emparejarse sin problemas (en teoría la señal Z-Wave es de aproximadamente unos 20 metros, por eso si no detecta, es que a lo mejor está demasiado lejos, de todas formas el Fibaro Wall Plug tiene un botón en la parte inferior que permite realizar una sincronización forzada, leer el manual de uso, pero a mi siempre me lo ha detectado a la primera)

fibaro wall plug domotica

En el panel de control Web Razberry Z-Wave vamos a Devices configuration y en la parte inferior derecha pulsamos en Expert mode. En la lista de dispositivos en la parte izquierda debería aparecer nuestro Fibaro Wall-Plug, si picamos sobre el y vamos a la parte inferior de la lista de opciones deberíamos ver un menú desplegable llamado Advanced Actions. Dentro pulsamos en Show Interview Results. Si pulsamos en SensorMultiLevel podemos ver todos los datos necesarios para configurar a continuación un acceso a la API de Razberry Z-Wave fundamental para montar nuestro pequeño programa casero para extraer información del sensor. Esto es aplicable a todos los dispositivos que emparejemos con nuestro dispositivo

zwave web razberry domotica

En mi ejemplo si nos damos cuenta, el acceso al Sensor Multi Nivel de la Razberry, se realiza desde devices[2].instances[0].commandClasses[49].data[4].val (en caso de data hay para elegir el 0 y el 4, como quiero sacar el dato en val que es el consumo en Vatios (W) en el momento concreto, pues elijo el 4 y la propiedad “val”).

Para confirmar que todo va bien, podemos acceder a este valor a través de la API de Razberry a través de la dirección (con la propiedad value al final para que nos devuelva el valor)

http://ip_raspberry_pi:8083/ZWaveAPI/Run/devices[2].instances[0].commandClasses[49].data[4].val.value

Si vemos un valor significa que todo va bien (es posible que los valores cambien de dispositivo a dispositivo, por eso he indicado como yo he llegado a estos valores específicamente)

Programación utilizando la API de Razberry y el Fibaro Wall Plug

Ahora mi objetivo es crear un script en PHP que vaya metiendo en una base de datos cada 5 minutos este valor a través de la librería cURL. Dado que la Raspberry Pi no está para trotes, he decidido usar la base de datos SQLite. Creamos la base de datos con el nombre que queramos que es un fichero al final de cuentas, si ya tenemos SQLite instalado y un servidor web con la extensión de PHP (en mi caso puse apache2 como servidor web que aunque es pesado lo conozco mejor, aunque quizá sería más recomendable lighthttp) podemos crear la base de datos con el comando:

# sqlite3 razberry.db

Luego desde la interfaz sqlite3 podemos crear la tabla por ejemplo “plug” con los comandos clásicos de SQL. Nos van a hacer falta unos 4 campos:

  • Un identificador único INTEGER llamado id con autoincremento (no es fundamental, pero nunca está de mas)
  • Un parámetro tipo DATETIME llamémosle fecha
  • Un parámetro tipo REAL llamado valor
  • Un parámetro tipo INTEGER llamado disp. (tampoco es fundamental, pero es práctico para llevar un control de sucesivos dispositivos específicos y no mezclar datos, aparte que me va a servir para simplificar la programación al máximo a efectos explicativos)

El script en PHP es el siguiente, llamémosle /home/pi/consumo.php

#!/usr/bin/php
<?php
if (!function_exists('curl_init')){
die('Sorry cURL is not installed!');
}
$url = "http://ip_raspberry_pi:8083/ZWaveAPI/Run/devices[2].instances[0].commandClasses[49].data[4].val.value";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
class MiBD extends SQLite3{
function __construct()
{ $this->open('/var/www/razberry.db'); }
}
$bd = new MiBD();
$watios = curl_exec($ch);
$bd->exec("INSERT INTO plug (fecha,valor,disp) VALUES (datetime('now'),$watios,1)");
curl_close($ch);
?>

De aquí solo ver, que hacemos una llamada a la API con cURL para sacar el dato de consumo, y luego insertamos el datos en la tabla junto a la fecha del momento y marcamos el dispositivo número 1 (en este caso el primer dispositivo electrónico que vayamos a medir, luego si cambiamos de sitio el enchufe para domotica Fibaro Wall-plug podemos poner el número 2, 3 y así sucesivamente)

Ahora necesitamos un script para que corra este script en PHP cada 5 segundos, por ejemplo /home/pi/consumo.sh:

#!/bin/sh
(sleep 5 && /home/pi/consumo.php) &
(sleep 10 && /home/pi/consumo.php) &
(sleep 15 && /home/pi/consumo.php) &
(sleep 20 && /home/pi/consumo.php) &
(sleep 25 && /home/pi/consumo.php) &
(sleep 30 && /home/pi/consumo.php) &
(sleep 35 && /home/pi/consumo.php) &
(sleep 40 && /home/pi/consumo.php) &
(sleep 45 && /home/pi/consumo.php) &
(sleep 50 && /home/pi/consumo.php) &
(sleep 55 && /home/pi/consumo.php) &
(sleep 60 && /home/pi/consumo.php)

Lo admito: La elegancia programando no es lo mío, no me acordaba muy bien cómo eran los parámetros en Bash y prefería invertir el tiempo en esta entrada, que en dejarlo todo óptimo J

Finalmente vamos a poner este script con una línea en /etc/crontab:

* * * * * root /home/pi/plug.sh

Y ya debería funcionar cada 5 segundos, almacenando los datos de consumo en esos intervalos de tiempo.

Por último y para poner la guinda del pastel, si instalamos el servidor web Apache o LightHTTP como indicaba antes, podríamos tener un básico panel de control en PHP para saber la información que nos reporta esta base de datos (por ejemplo en /var/www/reportes.php)

<?php
class MiBD extends SQLite3
{
function __construct() { $this->open('/var/www/razberry.db'); }
}
$bd = new MiBD();
$resultado = $bd->query("SELECT AVG(valor),COUNT(valor) FROM plug WHERE (fecha > datetime('now','-24 hours')) AND (fecha < datetime('now')) AND (disp = 1)");
$res = $resultado->fetchArray();
$kwh = 0.162; // El coste el KWH de vuestra compañía de Luz
echo "Potencia Media en las ultimas 24 horas: ".$res[0]." W";
echo "<br/> Numero Registros: ".$res[1];
$coste = $res[0]/1000 * $kwh * 24 * 30;
echo "<br/> Coste Mensual: ".$coste." euros";
if (!function_exists('curl_init')){
die('Sorry cURL is not installed!');
}
$url = "http://ip_de_raspberry:8083/ZWaveAPI/Run/devices[2].instances[0].commandClasses[49].data[4].val.value";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$watios = curl_exec($ch);
echo "<br/> Consumo Actual: ".$watios." W";
?>

Y ahora me entero que mi emisor térmico efectivamente, no gasta tanto como creía:

Potencia Media en las últimas 24 horas: 150.13031858033 W
Numero Registros: 17273
Coste Mensual: 17.51120035921 euros
Consumo Actual: 282.6000128 W

Espero que os sirva de provecho esta guía para tener un pequeño Z-Wave casero. En un futuro, intentare adquirir algún producto adicional Z-Wave (un sensor de movimiento y una alarma por ejemplo), y planteare “fusionar” el mundo de la Domotica con Asterisk

 

Montando un Sistema Asterisk Autonomo I

Durante el curso de Asterisk Advanced, una de las cuestiones que surgieron con los compañeros, era el tema de la “practicidad” eventual que podia surgir a la hora de decidir montar una interfaz grafica a pesar de que muchos hayan criticado, es el simple hecho que otorga un “sistema” para que manos inexpertas (bajo nuestra aprobacion y previamente formados), puedan tomar el control de nuestro Asterisk sin nuestra supervision constante.

Evidentemente surgen algunas inconveniencias, que son inevitables en este tipo de situaciones, pero en las manos adecuadas, pueden ser mas pros que contras (por ejemplo explicandole a un equipo tecnico o IT funcionalidades basicas de Asterisk como crear nuevas extensiones para poder cursar llamadas. De esto se trata la idea de montar un sistema Autonomo (al menos autonomamente de nuestra persona).

Un paso mas alla, viendo el sistema RealTime de Asterisk, se me ocurrio la -evidente- idea de crear una micro interfaz grafica (por ejemplo basada en web con PHP como sera el caso que exponga a continuacion), para gestionar esos aspectos de Asterisk especificos, y poder definitivamente, tomando esto como ejemplo generico, poder obviar todas esas interfaces graficas (ejemplo FreePBX) para siempre.

Lo que me planteo de ejemplo ahora: Activar RealTime para los “peers” SIP de nuestro Asterisk y crear la interfaz grafica web en PHP para Crear y Borrar estas extensiones (La funcion de editar seria Borrar y volver a crear para este ejemplo sencillo, aunque realmente no seria nada dificil de implementar)

Como ya comente en su momento en otro mensaje, el montaje de un sistema RealTime es verdaderamente secuencial, es mas ya lo hicimos en las practicas durante Asterisk Advanced en detalle.

En primer lugar, obviamente necesitamos tener instalado un sistema de gestion de bases de datos como MySQL, tambien un servidor web como Apache, y los modulos de PHP para el mismo. En este caso, como ya vimos antes, LAMP es lo ideal. Asi que ejecutamos tasksel y lo instalamos (LAMP Server, Ubuntu/Debian)

Tambien necesitamos las librerias de ODBC puesto que vamos a utilizarlas con Asterisk:

# aptitude install unixodbc libmyodbc

En segundo lugar, configuramos la base de datos y la tabla donde volcar los usuarios SIP:

– Creamos un fichero por ejemplo en /tmp/ llamado por ejemplo sip_buddies.sql con esta informacion (se puede encontrar mas informa acerca de la tabla asociada a los peers SIP  aqui). Atencion al ultimo campo que coloreo en Rojo. Muy importante que lo agreguéis manualmente para lo que vamos a tratar de hacer a continuacion

CREATE TABLE `sip_buddies` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(80) NOT NULL default ”,
`host` varchar(31) NOT NULL default ”,
`nat` varchar(5) NOT NULL default ‘no’,
`type` enum(‘user’,’peer’,’friend’) NOT NULL default ‘friend’,
`accountcode` varchar(20) default NULL,
`amaflags` varchar(13) default NULL,
`call-limit` smallint(5) unsigned default NULL,
`callgroup` varchar(10) default NULL,
`callerid` varchar(80) default NULL,
`cancallforward` char(3) default ‘yes’,
`canreinvite` char(3) default ‘yes’,
`context` varchar(80) default NULL,
`defaultip` varchar(15) default NULL,
`dtmfmode` varchar(7) default NULL,
`fromuser` varchar(80) default NULL,
`fromdomain` varchar(80) default NULL,
`insecure` varchar(4) default NULL,
`language` char(2) default NULL,
`mailbox` varchar(50) default NULL,
`md5secret` varchar(80) default NULL,
`deny` varchar(95) default NULL,
`permit` varchar(95) default NULL,
`mask` varchar(95) default NULL,
`musiconhold` varchar(100) default NULL,
`pickupgroup` varchar(10) default NULL,
`qualify` char(3) default NULL,
`regexten` varchar(80) default NULL,
`restrictcid` char(3) default NULL,
`rtptimeout` char(3) default NULL,
`rtpholdtimeout` char(3) default NULL,
`secret` varchar(80) default NULL,
`setvar` varchar(100) default NULL,
`disallow` varchar(100) default ‘all’,
`allow` varchar(100) default ‘g729;ilbc;gsm;ulaw;alaw’,
`fullcontact` varchar(80) NOT NULL default ”,
`ipaddr` varchar(15) NOT NULL default ”,
`port` smallint(5) unsigned NOT NULL default ‘0’,
`regserver` varchar(100) default NULL,
`regseconds` int(11) NOT NULL default ‘0’,
`lastms` int(11) NOT NULL default ‘0’,
`username` varchar(80) NOT NULL default ”,
`defaultuser` varchar(80) NOT NULL default ”,
`subscribecontext` varchar(80) default NULL,
`useragent` varchar(20) default NULL,
`useradmin`  int(1) NOT NULL DEFAULT ‘0’,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
KEY `name_2` (`name`)
) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;

#mysql -p
Entramos con nuestra password
mysql> create database asterisk;
mysql> use asterisk;
mysql> source /tmp/sip_buddies.sql

En tercer lugar vamos a configurar los ficheros basicos de Asterisk para poder trabajar con el conector ODBC

/etc/asterisk/extconfig.conf

[settings]
sippeers => odbc,asterisk ,sip_buddies

/etc/asterisk/res_odbc.conf

[asterisk]
enabled => yes
pre-connect => yes
dsn => asterisk
username => root
password => (el password que le pusimos al usuario de la base de datos mysql root durante la configuracion de LAMP)

/etc/odbc.ini

[asterisk]
Description = ODBC para MySQL
Driver = MySQL
Server = localhost
Database = asterisk
Socket = /var/run/mysqld/mysqld.sock

/etc/odbcinst.ini

[MySQL]
Description = MySQL ODBC MyODBC Driver
Driver = /usr/lib/odbc/libmyodbc.so
Setup = /usr/lib/odbc/libodbcmyS.so

Con esto vamos al CLI de Asterisk
# asterisk -r
CLI> odbc show

Y si vemos “Connected: Yes” entonces ya esta preparado

En cuarto lugar vamos a configurar los usuarios SIP:

Para ello creamos un fichero temporal por ejemplo /tmp/usuarios_sip_buddies.sql con la siguiente info:

INSERT INTO sip_buddies (`name`, `host`, `nat`, `type`, `cancallforward`, `canreinvite`, `context`, `md5secret`, `qualify`, `disallow`, `allow`, `fullcontact`, `ipaddr`, `port`, `regseconds`, `lastms`, `username`, `defaultuser`)
VALUES (‘ext10’, ‘dynamic’, ‘no’, ‘friend’, ‘yes’, ‘yes’, ‘extensiones’, ‘e8a325cb599ad4b6eb95d79aa4506ed2’, ‘yes’, ‘all’, ‘g729;ilbc;gsm;ulaw;alaw’, ”, ”, ‘0’,’0′, ‘0’, ”, ”)

Importante, el ultimo valor a 1, y la clave sera 1234 en formato md5 evidentemente se deberia cambiar.

Ahora como antes lo ejecutamos desde el interfaz de comandos de MySQL

#mysql -p
mysql> use asterisk;
mysql> source /etc/usuarios_sip_buddies.sql

Finalmente necesitamos editar el fichero sip.conf con una configuracion minima. Por ejemplo:

/etc/asterisk/sip.conf

[general]
language = es

Desde este mismo momento ya tenemos el usuario sip ext10 con la clave 1234 listo para funcionar. Podemos probarlo con cualquier telefono SIP.

Puede parecer muchisima historia comparado a configurar un fichero sip.conf, pero con la practica y unas plantillas, esta gestion se realiza en 5 minutos y ahora viene la “potencia”.

El script PHP:

Voy a crear un solo fichero PHP al estilo monolitico para que funcione y nada mas. Evidentemente sera bastante mejorable y ya esta en nuestras manos con unos conocimientos basicos de programacion PHP (y obviamente adaptable a cualquier otro lenguaje de programacion con el que nos sintamos mas comodos)

Lo primero vamos a crear algunos directorios dentro del lugar donde tengamos publicado el servidor web apache, por defecto /var/www
# cd /var/www
# mkdir asterisk
# cd asterisk
# mkdir sip
# cd sip

Ahora vamos a crear un fichero index.php con el siguiente contenido:

 <?php

// Conexion a la base de Datos

$base = "asterisk";
$host = "localhost";
$user = "root";
$password = "nuestra_contraseña_sql";
$conexion = mysql_connect($host,$user,$password);
$result = mysql_select_db($base,$conexion) or die ("Error en la Conexion a BD");

session_start();

// Si no estamos logeados

if (!$_SESSION['login'])
{
 if(isset($_POST['loginsubmit']))
 {
 $usuario = $_POST['usuario'];
 $password = $_POST['password'];

 if((!$usuario) || (!$password))
 {
 echo "Error 1<br>";
 exit();
 }
 $password = $usuario.":asterisk:".$password;
 $password = md5($password);
 $query = mysql_query("SELECT * FROM sip_buddies WHERE name='$usuario' AND md5secret = '$password' AND useradmin = '1'");
 if (mysql_num_rows($query) > 0)
 {
 session_register('login');
 $_SESSION['login'] = '1';
 }
 else
 echo "Error 2<br><br>";

 echo "<a href='index.php'>Home</a>";
 }
 else
 {
 echo "<form method='post' action='?'>";
 echo "Usuario: <input name='usuario' type='text'><br>";
 echo "Contrase&ntilde;a: <input name='password' type='password'><br>";
 echo "<input type='submit' name='loginsubmit'>";
 echo "</form>";
 }

}
// Si ya estamos logeados

else
{
 // Salida del Sistema
 if(isset($_REQUEST['exit']))
 {
 session_destroy();

 if(!session_is_registered('login'))
 echo "<a href='index.php'>Home</a>";

 }
 // Insercion de un nuevo Registro
 elseif(isset($_POST['insertsubmit']))
 {
 $sipuser = $_POST['sipuser'];
 $sippass = $_POST['sippass'];
 $sippass = $sipuser.":asterisk:".$sippass;
 $sippass = md5($sippass);
 $query = mysql_query("INSERT INTO sip_buddies (`name`, `host`, `nat`, `type`, `cancallforward`, `canreinvite`, `context`, 
 `md5secret`, `qualify`, `disallow`, `allow`, `fullcontact`, `ipaddr`, `port`, `regseconds`, `lastms`, `username`, `defaultuser`) 
 VALUES ('$sipuser', 'dynamic', 'no', 'friend', 'yes', 'yes', 'extensiones', '$sippass', 'yes', 'all', 'g729;ilbc;gsm;ulaw;alaw', '', '', 
 '0','0', '0', '', '')");

 echo "<a href='index.php'>Home</a><br>";
 echo "<a href='index.php?exit'>Exit</a>";
 }
 // Borrado de un Registro
 elseif(isset($_POST['deletesubmit']))
 {
 $sipid = $_POST['sipid'];
 $query = mysql_query("DELETE FROM sip_buddies WHERE id = '$sipid'");

 echo "<a href='index.php'>Home</a><br>";
 echo "<a href='index.php?exit'>Exit</a>";
 }
 // Formularios de Insercion y Borrado
 else
 {
 echo "Insertar Registro:<br>"; 
 echo "<p><form method='post' action='?'>";
 echo "Usuario: <input name='sipuser' type='text'><br>";
 echo "Contrase&ntilde;a: <input name='sippass' type='password'><br>";
 echo "<input type='submit' name='insertsubmit' value='Insertar'>";
 echo "</form></p>";

 echo "<table border='1'>";
 echo "<tr><td colspan ='2' align='center'>SIP Peers Activos</td></tr>";
 echo "<tr><td>Usuario</td><td>Borrar</td></tr>"; 

 $query = mysql_query("SELECT * FROM sip_buddies WHERE type = 'friend'");
 $rows = mysql_num_rows($query);
 for ($i=0;$i<$rows;$i++)
 {
 $sippeersarray = mysql_fetch_array($query);
 $sipuser = $sippeersarray['name'];
 $sipid = $sippeersarray['id'];

 echo "<tr>";
 echo "<td>".$sipuser."</td>";
 echo "<td>";
 echo "<form method='post' action='?'>";
 echo "<input type=hidden name='sipid' value='$sipid'>";
 echo "<input type=submit name='deletesubmit' value='Borrar'>";
 echo "</form>";
 echo "</td>"; 
 echo "</tr>";

 } 
 echo "</table>"; 
 echo "<a href='index.php?exit'>Exit</a>";

 }
}

?>

Y eso es todo, ahora podemos acceder a traves de un navegador a la direccion:

http://ip_nuestro_servidor_asterisk/asterisk/sip/

Y aparecera para introducir un usuario y contraseña. Siguiendo el ejemplo seria Usuario: ext10,  Contraseña: 1234

Asi accederiamos a la micro interfaz para Crear y Borrar extensiones.

Evidentemente este codigo tiene bastantes deficiencias “tecnicas”, por ejemplo se podria intentar realizar una tecnica de Inyeccion de Codigo SQL para logearnos como el usuario administrador por las “bravas”, y ya conociendo la estructura, hasta darnos de alta un usuario Administrador para acceder siempre. Pero la idea basica era poder ejemplificar lo que queria mostrar con este articulo, que con solo seguir unos pasos de 5 minutos o menos, y tener este script PHP listo para ser “insertado” en el servidor web, tendriamos una interfaz totalmente Autonoma para nuestro cliente, equivalente a la que “instalamos” en mensajes anteriores, para la gestion de salas de conferencias MeetMe.

Ademas esta claro este codigo se podria mejorar para añadir la posibilidad de editar extensiones, o incluso configurar mas parametros de las extensiones (o tener dos interfaces, una de administrador para nosotros mismos, y otra para los usuarios), asi no tendriamos que andar “trasteando” directamente en el interfaz MySQL si modificamos regularmente las extensiones.

Con esto, ya empiezan a haber motivos para poder ir planteandonos dar un primer paso y dar fin a las interfaces graficas de Asterisk!.

Tengo que reconocer que este mensaje me ha llevado componerlo mas tiempo del previsto originalmente. Toda mejora al codigo, o sugerencia como siempre, sera ampliamente agradecida a traves de los comentarios.

MeetMe in a Box: Web-MeetMe: Conferencias de Audio de altos vuelos.

Hoy en día es muy común ver multitud de software web, capaz de ofrecer funcionalidades de conferencias online, webminars (seminarios web), y videoconferencias llevadas a reuniones. Llegaremos a eso algún día, pero como para ello se requiere el software, y el hardware especifico (y de calidad), y en estos momentos como todos sabemos, el horno no está para bollos (pese a que la gran mayoría sabemos a día de hoy lo que nos podríamos ahorrar, existen aún defensores, como George Clooney en “Up in the Air” que defienden “lo presencial”).

De momento no vamos a conformarnos con poco, y vamos a tratar de montar un sistemas de conferencias por Audio, de bajo coste, y si puede ser con Teléfonos de por medio, que hoy en día, las llamadas a fijos están muy baratas y dan una calidad de audio ““streaming”” excepcional.

Y a este sistema, Asterisk lo llamó MeetMe. Y realmente es tan simple como el tema de los buzones de voz (incluso más simple aun!) con su Aplicación con el mismo nombre, y su fichero de configuración meetme.conf. Pero voy a dar un paso más allá: Haciendo uso de esta base, poder obtener el potencial de un sistema de Gestión de Conferencias de Audio en tiempo real, a través de una Interfaz Web. Esto, realmente suena mucho mejor que “una conferencia a tres (o a cuatro)”, como quien dice. Vamos allá.

Para la Interfaz Web MeetMe van a hacer falta algunos elementos. Algunos ya los tendremos si hicimos la instalación de LAMP en su día.

En primera instancia vamos a ir descargando el paquete estrella, la interfaz Web-MeetMe. La página oficial seria: https://sourceforge.net/projects/web-meetme/

# tar –xvf web-meetme_(versión que sea)
# cd web-meetme

En primer lugar toca configurar el Driver ODBC para conectar con nuestra base de datos MySQL. Hay que instalar algunos detalles para el ODBC de nuestro sistema
# aptitude install unix-odbc
# aptitude install libmyodbc

Ahora configuramos el driver en condiciones. Primero editamos /etc/odbcinst.ini para crear un driver a MySQL:

[MySQL]
Description = MySQL ODBC MyODBC Driver
Driver = /usr/lib/odbc/libmyodbc.so
Setup = /usr/lib/odbc/libodbcmyS.so

Luego configuramos el fichero /etc/odbc.ini con la siguiente información.

[meetme]
Description = ODBC para MySQL
Driver = MySQL
Server = localhost (local, o servidor donde tengamos la base de datos con el driver ODBC)
Database = meetme (tenemos que crear una base de datos igual que la de Asterisk, pero con este nombre, para diferenciar un poco, en mysql,
Port = 3306
User            = asterisk
Password        = asterisk
Socket = /var/run/mysqld/mysqld.sock (puede que este fichero de socket este en otro sitio dependiendo la distribución donde tenemos nuestro sistema)
Stmt =
Trace = yes
TraceFile = /tmp/odbc.log

No entro en detalles, porque esto es configuración del conector ODBC para acceder a nuestra base de datos MySQL que supuestamente, ya tenemos instalada.

Para configurar la nueva base de datos meetme, simplemente podemos entrar en la consola mysql #mysql –u asterisk –p y poner el comando: CREATE DATABASE `meetme` ;

A partir de ahí generamos las tablas. Si no hemos salido del directorio web-meetme del paquete que descargamos antes ejecutamos:
# mysql –u asterisk –p < ./cbmysql/db-table-create-(version-que-sea).txt
# mysql –u asterisk –p < ./cbmysql/upgrade-db.txt

Ahora realizamos la configuración del conector ODBC de Asterisk, el fichero de configuración es /etc/asterisk/res_odbc.conf, creando un contexto específico para meetme.

[meetme]
dsn => meetme (este es el contexto que creamos antes en el sistema)
username => asterisk (supuestamente va a ser nuestro usuario para asuntos de Asterisk y servidor de base de datos)
password => asterisk (o la que le pusiéramos)
pre-connect => yes

Ahora en extconfig.conf (si tenemos el fichero de ejemplo, tan solo buscamos la línea meetme => y cambiamos lo que haya al completo por:
meetme => odbc,meetme,booking

Como todo lo hacemos a través del driver ODBC pues los Call Detail Records, los vamos a registrar de esta manera también. En el fichero cdr_adaptative_odbc.conf:

[wmm]
connection=meetme
// este es el context que utilizamos antes en res_odbc.conf)
table=cdr
// vamos a llamar a la tabla igual que la llamamos en la bbdd Asterisk. Realmente podríamos basarnos en la misma base de datos que ya tenemos, pero en este caso, para que no sea estrictamente necesario seguir el planteamiento de CDR-Stats vamos a independizarlo.

También hace falta introducir una pequeña opción en meetme.conf para evitar usar una columna del Asterisk RealTime para meetme que web-meetme no utiliza:

logmembercount=no

Después de esto tenemos una opción para acceder al sistema utilizando un servicio LDAP, o utilizando usuarios creados a mano en la base de datos. En nuestro caso de momento, vamos con esta opción, ya que a priori tampoco deberíamos tener tantos… o sí. Me apunto esto para en un futuro, actualizar con un sistema LDAP como ampliación del poder de Asterisk + LINUX. Para crear la estructura de la tabla “user”, como antes en el directorio web-meetme ejecutamos:
# mysql –u asterisk –p < ./cbmysql/db-admin-user-create.txt

Con esto ya tenemos creada la base del sistema.

Ahora vamos a configurar el sistema Web-Meetme en si.

En primer lugar tenemos que preparar la interfaz web dentro de nuestro directorio raíz donde se publican las web de nuestro servidor Apache. Por regla general y por defecto suele ser /var/www. Ahí podemos crear un nuevo directorio específico para Web-Meetme
#mkdir /var/www/web-meetme

Ahora vamos a copiar todo el tarball que descargamos al principio de Web-Meetme en este directorio recién creado:

#cp –r /ruta/donde/este/nuestro/tarball/descomprimido /var/www/web-meetme

Ahora toca configurar los parámetros de nuestra Interfaz Web en los ficheros de configuración de la misma, en primer lugar dentro del directorio raíz de web-meetme vamos /lib/defines.php de momento lo básico es configurar los datos de acceso a nuestra base de datos y algunos campos clave:

define (“WEBROOT”, “http://ip-nuestro-servidor/web-meetme/”);
// La dirección web relativa de nuestro
define (“FSROOT”, “/var/www/web-meetme/”);
// La ruta a la interfaz
define (“LIBDIR”, FSROOT.”lib/”);
// Esto tal cual

Finalmente editamos una más, para identificación de usuarios, en nuestro caso habíamos creado una tabla “user” (automáticamente durante el proceso de carga de datos SQL que hicimos antes) dentro de nuestra base de datos meetme para la administración de usuarios:

define (“AUTH_TYPE”, “sqldb”); // adLDAP or sqldb

Existe un usuario en la base de datos administrador creado por defecto. Que luego usaremos para acceder el sistema y poder crear usuarios adicionales personalizados.
Usuario: wmm@localhost
Password: wmmpw

También es necesario configurar los parámetros de la base de datos. En este caso se realiza desde el fichero dentro de /lib/database.php:

$database = ‘meetme’;
$host = ‘localhost’;
$username = ‘asterisk’;
$password = ‘asterisk’;

Si os fijáis este fichero hace referencia a un módulo DB.php. Para poder hacer uso de este también es necesario instalar un paquete, php-pear y su módulo db
# aptitude install php-pear
# pear install db
El caso es que al parecer el modulo db ha quedado obsoleto y lo sustituye mdb2
# pear install mdb2 (aunque con el primero ya es suficiente en el momento que escribo este artículo)

Por otro lado nos toca configurar la interfaz para comunicarse con el Asterisk Manager. Para ello debemos configurar primero el manager de Asterisk y añadir un usuario para esto específico. En el directorio /etc/asterisk, fichero manager.conf, creamos un nuevo contexto, que va a ser justamente el usuario que vamos a utilizar:

[meetme]
secret = meetme (la password que queramos)
read = call
write = command,originate
Y luego como siempre #asterisk –rx ‘manager reload’

Y ahora en el directorio de la interfaz web de Web-Meetme, dentro de /phpagi tenemos un fichero de configuración de ejemplo que vamos a utilizar
#cd /var/www/web-meetme/phpagi
#cp phpagi.example.conf /etc/asterisk/phpagi.conf

Y lo editamos asi:
# vim /etc/asterisk/phpagi.conf

Dentro de [asmanager]
server=localhost
port=5038
username=meetme
secret=meetme

También tenemos que editar el fichero index.html para adaptarlo a la ruta relativa de nuestra web. Algo así:

<META HTTP-EQUIV=”REFRESH” CONTENT=”0; URL=http://servidor_ip/web-meetme/meetme_control.php”>

Y ya está todo lo básico. Ahora podemos acceder a nuestro sistema Web MeetMe desde
http://ip_servidor/web-meetme

Lo último de todo sería configurar una marcación en el extensions.conf para poder acceder a nuestro sistema, sea desde un DID que tuviéramos configurado, o directamente a la extensión en concreto. Por ejemplo:

exten => 5000,1,NoOp()
exten => 5000,n,Answer
exten => 5000,n,MeetMe()

Y con esto marcando el 5000 si en la interfaz habíamos creado un número de conferencia, nos pedirá, el número de conferencia y el PIN asignado para acceder a la misma.

Lo más curioso de esto es que en este proyecto también está presente Areski Belaid, creador del CDR-Stats y también de A2Billing, uno de  “tarificadores” más reconocidos en Asterisk, y desde este Blog agradecemos sus contribuciones al mundo de la Interfaz web para Asterisk.

Otras curiosidades que he encontrado, php-agi no está diseñado para trabajar con una version PHP superior a 5.2. Es por esto por lo que aparece un error en el log de apache constante:

PHP Parse error:  syntax error, unexpected T_GOTO, expecting T_STRING

La solución a este problema es muy fácil, la function goto está obsoleta, por eso vamos a nuestro directorio de web-meetme /var/www/web-meetme/phpagi y dentro modificamos el fichero phpagi.php, vamos a la línea donde aparece:

“function goto”

Y la cambiamos por “function goto2”. Así de simple.

Así el sistema quedaría configurado como para poder crear una sala de conferencias, visualizar los usuarios, expulsarlos a voluntad, bloquearles el micrófono, gestiones simples de administración de conferencias… aunque todavía no he llegado a alcanzar el 100% de la funcionalidad. La documentación es muy pobre, y mis vanos intentos de conseguir resultados no han llegado a buen puerto. Por ejemplo la función de Invite, para poder ser aplicada a través de un Troncal SIP, no consigo hacer que el sistema se autentifique correctamente para lanzar la llamada a través del mismo. La mayor parte de la configuración se consigue editando las variables del fichero defines.php, aun así, he de reconocer que el software tiene un nivel de personalización bastante grande, ya entrare en detalles sobre esto en otro momento. Al menos con esto es posible tener en marcha lo básico para poder trabajar eficientemente.