Archivo de la etiqueta: Python

Añadiendo soporte de GPIO a Asiri

Si tuviste la suerte de recibir una placa Asiri en ElastixWorld, y seguiste la guía que escribí ayer, deberías tener una placa Asiri con uElastix funcionando sin problemas. Mola y todo eso, pero hoy en día los puertos GPIO son la moda, y como Asiri no tiene pues tenemos que hacer algo al respecto.

Antes de empezar, y para que quede claro, ¿qué es GPIO? La Wikipedia nos ayuda:

GPIO (General Purpose Input/Output = Entrada/Salida de Propósito General) es un pin genérico en un chip, cuyo comportamiento (incluyendo si es un pin de entrada o salida) se puede controlar (programar) por el usuario en tiempo de ejecución.

Vamos al lío. Lo primero que hice al recibir mi Asiri fue ir a la página web para ver que clase de puertos y conectores tenía, y me llevé una agradable sorpresa al ver que disponía de un puerto I2C:

asiri-board

 

La placa Asiri que me tocó a mi no tenía soldado un header en el puerto I2C, así que lo primero que tenemos que hacer es soldar un header de 4 pines para facilitar las conexiones:

asiri-header1

 

Así quedará con los cables conectados:

asiri-header2

 

I2C es un bus de comunicaciones en serie, y gracias a mis aventuras con el hardware ya conocía la manera de utilizarlo para GPIO, con la ayuda de un chip MCP230xx.

Los chips MCP23008 y MCP23017 son unos circuitos integrados muy baratos (menos de $2) que nos ofrecen 8 y 16 puertos GPIO respectivamente y se conectan a otro circuito mediante I2C, así que parece que estamos de suerte. Yo tengo un MCP23017 (el de 16 puertos GPIO) así que usaré ese para los ejemplos aquí expuestos. Veamos el chip:

mcp23017-pinout

 

Para funcionar con él, realizaremos las siguientes conexiones en nuestro breadboard:

  • A0, A1, A2: GND. Con estos pines se controla la identificación del chip en el bus I2C, ya que es posible encadenar varios. En éste caso conectamos todos a GND porque solo tenemos un chip.
  • RESET: +3.3V. La línea reset ha de estar conectada a voltaje positivo.
  • VDD: +3.3V.
  • VSS: GND.
  • SDA: conectado al pin SDA del puerto I2C de Asiri.
  • SCL: conectado el pin SCL del puerto I2C de Asiri.

Los 16 puertos GPIO del chip se reparten en 2 bancos de 8, numerados GPA0-7 y GPB0-7.

Una vez hemos realizado las conexiones necesarias, vamos a ver si el sistema detecta el chip. Para ello vamos a cargar el módulo del kernel necesario e instalar el paquete de herramientas de manejo del puerto I2C:

modprobe i2c-dev
yum install i2c-tools

 

Vemos si el kernel ha creado el dispositivo I2C en /dev:

[root@uelx ~]# ls -l /dev/i2c*
crw------- 1 root root 89, 1 Dec 31  1999 /dev/i2c-1
[root@uelx ~]#

 

¡Parece que si! A ver si vemos el chip…

[root@uelx ~]# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- 08 -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
[root@uelx ~]#

 

Yeah, ahí está, en la dirección 0x20. Ahora vamos a montar un pequeño circuito con un LED para probar si la cosa realmente funciona:

Asiri-MCP23017_bb

Vamos a utilizar la herramienta i2cset del paquete i2c-tools que instalamos antes para encender y apagar el LED:

# configurar GPB0 como salida
i2cset -y 1 0x20 0x01 0x00
# activar GPB0, encender el LED
i2cset -y 1 0x20 0x13 0x01
# apagar el LED
i2cset -y 1 0x20 0x13 0x00

 

Si todo ha ido bien, deberíais ver que el LED se enciende con la segunda instrucción y se apaga con la tercera.

Como manejar el asunto así es un poco tedioso, he hecho una pequeña librería para el manejo de GPIO en Asiri con Python: python-asiri.

La librería depende del módulo smbus, que desafortunadamente no está disponible en los repositorios de Fedora Core 17, pero no pasa nada, vamos a compilarlo a mano:

wget http://dl.lm-sensors.org/i2c-tools/releases/i2c-tools-3.1.0.tar.bz2
tar jxvf i2c-tools-3.1.0.tar.bz2
cd i2c-tools-3.1.0
export CFLAGS="-I`pwd`/include"
cd py-smbus
python setup.py build
python setup.py install

 

Y ahora ya podemos instalar python-asiri:

yum install git
git clone https://github.com/saghul/python-asiri
cd python-asiri
python setup.py install

 

En el directorio examples podéis encontrar un ejemplo de LED que parpadea y otro con un botón. Si habéis creado el circuito igual que en el diagrama de arriba, tendréis el LED conectado el puerto GPB0, es decir, el 8, por lo que el ejemplo funciona sin modificaciones:

cd examples
python blink.py

 

Si todo ha ido bien deberíais ver el LED parpadeando a intervalos de 1 segundo, hasta que pulséis Ctrl-C. ¡Lo hemos conseguido!

Y ahora os toca, ¿qué vais a construir con Asiri?

Probando el framework de comunicaciones Plivo

Plivo es un framework de comunicaciones creado alrededor de FreeSWITCH con la intención de proporcionar un entorno en el que desarrollar aplicaciones multimedia. Puede compararse con Twilio, pero con una importante diferencia: es Open Source.

Para hacernos una idea de la arquitectura del sistema completo podemos consultar la sección overview de su página web. Aquí una de las imágenes a modo resumen:

Ya que Plivo es una solución hosted, es decir, tenemos que instalar nuestro propio servidor, tendremos que hacer algo de trabajo antes de poder probar una aplicación hola-mundo, pero afortunadamente Plivo viene con unos cuantos scripts que nos harán la vida muy fácil. ¡Al tema!

Paso 1: Instalar FreeSWITCH

Partiremos de una Debian Squeeze recién instalada y utilizaremos el script de instalación provisto por Plivo. La razón es que necesitamos una configuración específica para trabajar con Plivo y el script ya lo hace todo solo 😉 Podemos consultar algo más de documentación en la sección get started.

# wget --no-check-certificate https://github.com/plivo/plivo/raw/master/freeswitch/install.sh
# chmod +x install.sh
# ./install.sh

Una vez tenemos FreeSWITCH instalado (estará en /usr/lcoal/freeswitch/) podemos arrancarlo en background ejecutando:

# ./usr/local/freeswitch/bin/freeswitch -nc

Y podemos conectarnos a un CLI interactivo así:

# ./usr/local/freeswitch/bin/fs_cli

Paso 2: Instalar Plivo

Para instalar Plivo también utilizaremos un script y lo instalaremos en /opt/plivo/:

# wget --no-check-certificate https://github.com/plivo/plivo/raw/master/scripts/plivo_install_beta.sh
# chmod +x plivo_install_beta.sh
# ./plivo_install_beta.sh

Paso 3: Configurar Plivo

Una vez tenemos instalados FreeSWITCH y Plivo vamos a modificar ligeramente la condifuración de Plivo. Por defecto escucha peticiones del API REST en 127.0.0.1 (no Mike, creo que aún no soporta IPv6) así que lo cambiaremos para poder desarrollar en otra máquina.

Editamos el fichero /opt/plivo/etc/plivo/default.conf y configuramos la IP de la máquina donde tendremos nuestra aplicación escuchando:

...
DEFAULT_ANSWER_URL = http://192.168.99.53:5000/answered/
DEFAULT_HANGUP_URL = http://192.168.99.53:5000/hangup/
...
ALLOWED_IPS = 127.0.0.1,192.168.99.53
...
HTTP_ADDRESS = 0.0.0.0:8088
...
CALL_HEARTBEAT_URL = http://192.168.99.53:5000/heartbeat/

Ya estamos listos para arrancar Plivo:

/opt/plivo/bin/plivo start

Paso 4: Hola mundo

Ya tenemos todo listo ahora veámoslo en acción. El ejemplo a continuación está hecho echo en Python con Flask (un framework web) y hará que al llamar a sip:cualquiercosa@IP_de_nuestro_servidor:5080 se escuche “hello world” utilizando Text-To-Speech.

Esto tiene pinta de que me va a tener muy entretenido, ya iré posteando algo más a medida que lo vaya conociendo mejor.

Mandando comandos a OpenSIPS con mi_datagram

OpenSIPS dispone de diversos módulos mediante los cuales podemos enviar comandos para realizar determinadas acciones o consultar información. Podemos interactuar con OpenSIPS mediante un socket (mi_datagram) un fifo (mi_fifo) o XML-RPC (mi_xmlrpc).

Para mandar comandos sencillos podemos utilizar la herramienta de consola que ya viene con OpenSIPS opensipsctl, pero el fifo al que nos conectamos viene dado por el valor almacenado en un fichero (por defecto en /etc/opensips/opensipsctlrc), por lo tanto no es muy flexible si tenemos varias instancias de OpenSIPS corriendo en la misma máquina.

En MediaProxy y CallControl hacemos uso del módulo mi_datagram, para comunicarnos con OpenSIPS e indicarle que ha de terminar un diálogo, por ejemplo, por lo que pensé en reutilizar ese código para poder mandar comandos más fácilmente desde una interfaz de consola.

El resultado:

Un script que toma el comando que le pasemos por la línea de comando, lo formatea correctamente y lo envía al socket de OpenSIPS. Es bastante simple, pero nunca había probado el módulo stdio de Twisted, que permite hacer IO asíncrona de la entarda estándar, y ésta era una buena ocasión para probarlo. 😉

Jugando con Python en Android

Prácticamente todo lo que hay para Android esta hecho en Java, pero para los que nos dejó de molar hay alternativa: Android Scripting Environment.

ASE es una aplicación de Google gracias a la cual podemos instalar diversos lenguajes de scripting como Python, Perl, Lua, etc… Hasta ahora parece que la tenían un poco abandonada, pero han sacado dos versiones en la última semana, y por fin funciona sin tener que hacer nada a mano 🙂

Para instalarla basta con acceder a la web y bajarse el apk. Una vez instalamos la aplicación nos da la opción de instalar los diversos intérpretes, así que escogemos Python 😉 Además del propio intérprete se instalan varios scripts de demostración para empezar a jugar.

Happy coding!

4448535314_8f4d1998ca_o

4447762215_cc5b507710_o

4448540138_4649853595_o