Friday, December 30, 2011
Saturday, November 12, 2011
Saturday, October 29, 2011
Friday, October 21, 2011
Notes - Giving more stability to the mood lamp
I had some troubles setting up supervised process for the python binary running the mood lamp, I guess it might be related with the fact that python is also calling gnuplot subprocess via os.system call, and daemontools might be a bit lost with that (not sure).
So in order to have the binary running more stable and making it strong against spurious crashes I did a little script that is running under a screen session:
So in order to have the binary running more stable and making it strong against spurious crashes I did a little script that is running under a screen session:
#!/bin/bash
CRASH_COUNTER=0
while : ; do
python ./animo_mundial.py
let CRASH_COUNTER=$CRASH_COUNTER+1
echo $CRASH_COUNTER > /tmp/animo_crash_counter.txt
sleep 10
done
Saturday, October 01, 2011
Notes - Have seti@home graphics working with ubuntu
sudo xhost +si:localuser:boinc
this command in your System-Preferences-Sessions-Startup Programs:
/usr/bin/xhost +local:
If you want to run it at start up
sudo xhost +si:localuser:boinc
this command in your System-Preferences-Sessions-Startup Programs:
/usr/bin/xhost +local:
If you want to run it at start up
sudo xhost +si:localuser:boinc
Friday, September 30, 2011
Monday, September 19, 2011
Notes - Adding stability improvements to the mood lamp
If yo want to store chart data for public serving, It's necessary to have dropbox running, due to encryption issues maybe if you reboot your computer it will not run until you log in and mount your home so first thing run dropbox
service dropbox start
bash -c '/usr/bin/screen -dmS minic minicom -o'
#this is if you put some services with symlink under /service
#svscanboot will run them, but Im not using them form now
csh -cf '/command/svscanboot &'
#main soft running supervised and under a screen terminal
bash -c '/usr/bin/screen -dmS lamp supervise /home/me/scripts/animo'
service dropbox start
bash -c '/usr/bin/screen -dmS minic minicom -o'
#this is if you put some services with symlink under /service
#svscanboot will run them, but Im not using them form now
csh -cf '/command/svscanboot &'
#main soft running supervised and under a screen terminal
bash -c '/usr/bin/screen -dmS lamp supervise /home/me/scripts/animo'
Friday, September 16, 2011
Notes - Web scrapping ajax obfuscated websites
Im using a perl script that calls selenium server, then I use Beautiful soup to nicely parse the rendered output coming from selenium. Probably using webkit could be done more nicely but this way is easy and quick to setup.
Just wanted to write this note so I don't forget the pipes that I'm doing. :)
Really it is not needed to get data first with perl, rc selenium export to python (Remote Control) it is enough later to get the source and parse it.
To get the source code in python use:
data = sel.get_html_source()
if you're using perl:
my $data=$sel->get_html_source();
Just wanted to write this note so I don't forget the pipes that I'm doing. :)
Really it is not needed to get data first with perl, rc selenium export to python (Remote Control) it is enough later to get the source and parse it.
To get the source code in python use:
data = sel.get_html_source()
if you're using perl:
my $data=$sel->get_html_source();
Sunday, September 11, 2011
Notes - Monitor an event and send email when it occours
tail -f /var/log/messages | awk '/now/ {system("mail -s 'hi' myemail@mydomain.com < /dev/null")}'
interesting for /var/log/auth for example...
interesting for /var/log/auth for example...
Notes - Record shell session for later replay (educational use)
script -t 2> tutorial.timing -a tutorial.session
type ‘exit’ to end the recording.
Replay goes like this
scriptreplay tutorial.timing tutorial.session
type ‘exit’ to end the recording.
Replay goes like this
scriptreplay tutorial.timing tutorial.session
Notes - How to create an encrypted tar
tar -zcvf -stuff | openssl des3 -salt -k secret_pass | dd of=stuff.des3
didn't try it, juts took it from old notes.
Saturday, September 10, 2011
workaround for skype without headphones on ubuntu lucid 64
I was having some issues with skype and making it work in Ubuntu without using headphones. My monitor has built in camera and microphone that makes much more easy any videoconference.
The main issue was a kind of strange noise mixed with the output sound and incoming video not appearing.
So for the first issue, the strange noise, I had to disable pulseaudio by:
creating a client.conf in your .pulse dir in ~ and put the line "autospawn=no" in it. It would be good to turn back on autospawn after you have done what you need to do.
source: http://askubuntu.com/questions/8425/how-to-temporarily-disable-pulseaudio
To enable incoming video make sure cairo-dock is disabled, for some reason there is a bug that makes it interfere with X11 and skype.
But when re-running pulseaudio to get all controls back I get missing options, that I cannot figure out yet how to get, didnt spent more time on it, as this is an skype issue. Gmail video web conference have no problem at all with pulseaudio.
dani@mypc:~$ /usr/bin/pulseaudio --start --log-target=syslog
dani@mypc:~$ start-pulseaudio-x11
So had to comment out again the autospawn so pulse audio spawn during boot. At least useful to know it if someday for some reason you need to use skype.
Tuesday, September 06, 2011
Installing Latex gui Lyx from source
sudo su
aptitude install build-essential libqt4-dev libaspell-dev
cd /usr/local/src/
wget ftp://ftp.lyx.org/pub/lyx/stable/2.0.x/lyx-2.0.0.tar.gz
gzip -dc lyx-2.0.0.tar.gz | tar xf -
cd lyx-2.0.0
./configure
make
make install
apt-get install texlive-latex-extra
aptitude install build-essential libqt4-dev libaspell-dev
cd /usr/local/src/
wget ftp://ftp.lyx.org/pub/lyx/stable/2.0.x/lyx-2.0.0.tar.gz
gzip -dc lyx-2.0.0.tar.gz | tar xf -
cd lyx-2.0.0
./configure
make
make install
apt-get install texlive-latex-extra
Sunday, September 04, 2011
Installing ubuntu from Internet via usb key
Dammit, after 2 weeks vacations without using my main desktop pc, ubuntu natty stopped working. Don't have time to troubleshoot, so rolling back to LTS lucid.
Got the netboot.tar.gz file from:
http://archive.ubuntu.com/ubuntu/dists/lucid/main/installer-amd64/current/images/netboot/
and then wrote it to a usb key with imagewriter
sudo apt-get install usb-imagewriter
sudo usb-imagewriter
info from:
https://help.ubuntu.com/community/Installation/FromImgFiles
boot from usb and install
Got the netboot.tar.gz file from:
http://archive.ubuntu.com/ubuntu/dists/lucid/main/installer-amd64/current/images/netboot/
and then wrote it to a usb key with imagewriter
sudo apt-get install usb-imagewriter
sudo usb-imagewriter
info from:
https://help.ubuntu.com/community/Installation/FromImgFiles
boot from usb and install
Wednesday, August 24, 2011
Monday, August 15, 2011
Thursday, August 11, 2011
Tuesday, August 02, 2011
Saturday, July 30, 2011
27
Le encanta tomarse el café de los sábados junto a la ventana, dice que la temperatura es perfecta, diecisiete grados. Los ninyos por alguna extranya razón aun no están gritando en la calle con lo que todo esta muy tranquilo y puede escuchar como por una de esas ventanas, no se si es la mía, "fue en un pueblo con mar una noche"
Los barcos del río, aunque no consigue verlos desde su ventana, siguen atracados, como siempre, pero me ha dicho que las amarras que los unen a la ciudad se están debilitando y tarde o temprano zarparan, sin prisa pero sin pausa. Hace un tiempo fue capitán de uno de esos barcos, el mas bonito de todos, el que tenia escrito en su proa "Elle"
Se le termina el café, pero no hay problema ya que siempre hace para dos, sigue cocinando para dos y pone la mesa con unas velas, también se afeita y se pone camisa y esconde las piernas debajo de la mesa para que no se le vean las espardenyas que se le han roto porque como siempre se le olvid'o cortarse las unyas.
Se ha dado cuenta de que lo miraba por la ventana y ha cerrado una especie de cortina que m'as bien parece una s'abana, bueno, ya seguir'e mirando en otro momento o le llamo mas tarde para ver que hacemos.
Wednesday, July 27, 2011
Tuesday, July 26, 2011
Monday, July 25, 2011
22
Porque si decidiéramos irnos a algún lugar juntos me da miedo que un día… hoy no quizás… quizás… quizás mañana tampoco… pero un día de repente puede que empiece a llorar y llorar y llore tanto que nada ni nadie pueda pararme y que las lágrimas llenen la habitación y que me falte el aire y que te arrastre conmigo y que nos ahoguemos los dos.
La vida secreta de las palabras
Saturday, July 23, 2011
Wednesday, July 20, 2011
Sunday, July 17, 2011
14
Está lloviendo. Abro la ventana, me gusta escuchar el sonido de la lluvia golpeando las hojas de los árboles, no me importa que se mojen unos cuantos cables y una lámpara antigua que llevan años en esa esquina. No, no es la lámpara que mide las emociones, esa sigue desconectada encima de la mesa, me da miedo conectarla y ver que el azul no cambia de color. Ya la conectaré, tiene que pasar el tiempo y más ramas tienen que llegar a la ventana.
Saturday, July 16, 2011
Friday, July 15, 2011
Tuesday, July 12, 2011
Monday, July 11, 2011
8
Me estoy planteando no utilizar despertador. Llevo ya bastantes días en los que me despierto a una hora muy cercana a la que había fijado en el móvil, y es entonces cuando me toca desactivarlo para que no moleste mientras me preparo para salir. Me hace gracia porque hace poco estaba pendiente del móvil día tras día, el nexus one por alguna razón se estropeó y lo tuve que mandar a arreglar, con lo que al final estuve casi dos meses sin el dichoso móvil, y yo pensando en comprarme un despertador porque el móvil no llegaba...
Claro que entre semana pues piensas, oye esto no está del todo mal, pero claro llega el fin de semana y parece que el despertador corporal no tiene preferencias para ser cambiado y sigue despertándote a las 6 o 7. Estoy pensando seriamente envolverme en paquete y enviarme a arreglar dónde envié el móvil a ver si pueden hacer algo..
Sunday, July 10, 2011
Saturday, July 09, 2011
Sin hijo, ni árbol, ni libro. Silvio Rodriguez
Los hombres sin historia son la historia. Apiádense del hombre que no tuvo ni hijo, ni árbol, ni libro.
6
Últimamente todo lo que leo, veo o escucho me sorprende. Parece que día a día cada vez queda menos de eso que podemos llamar "valores" en el sentido ético o moral de la palabra, no en el sentido religioso. Sólo basta con poner la noticias durante un rato o mantener una conversación con un amigo y que te cuente lo que ocurre a su alrededor. ¿Qué está pasando? ¿nos estamos convirtiendo en animales?. La segunda pregunta tiene fácil respuesta, no, los animales en muchas ocasiones mantienen unos valores muy superiores a nosotros en relación al desarrollo cognitivo de su cerebro.
Pero a qué nos referimos cuando hablamos de valores, leyendo unas cuántas definiciones por Internet (en castellano) me quedo con aquella que aparece como primer resultado en Google, eso significa que se encuentra en ese primer puesto debido a que en la telaraña de la red, hay una gran mayoría de enlaces hacia ella, y eso en principio nos indicaría que esa definición o estudio estaría aceptada o reconocida por una mayor cantidad de gente.
Se entiende por valor moral todo aquello que lleve al hombre a defender y crecer en su dignidad de persona. El valor moral conduce al bien moral. Recordemos que bien es aquello que mejora, perfecciona, completa.
El valor moral perfecciona al hombre en cuanto a ser hombre, en su voluntad, en su libertad, en su razón. Se puede tener buena o mala salud, más o menos cultura, por ejemplo, pero esto no afecta directamente al ser hombre. Sin embargo vivir en la mentira, el hacer uso de la violencia o el cometer un fraude, degradan a la persona, empeoran al ser humano, lo deshumanizan. Por el contrario las acciones buenas, vivir la verdad, actuar con honestidad, el buscar la justicia, le perfeccionan.
El valor moral te lleva a construirte como hombre, a hacerte más humano.
En general podríamos agruparlos en la siguiente lista: el respeto, la tolerancia, la honestidad, la lealtad, el trabajo y la responsabilidad.
Ayer ví por primera vez V for Vendetta y me quedo con el discurso televisado de la película, lo puedes ver en:
Thursday, July 07, 2011
4
El bus de vuelta venía lleno como suele ser normal, así que me acerqué a la parte trasera dónde aún quedaban algunos sitios libres, estaba todo el suelo lleno de algo líquido, no quise investigar de que se trataba, así que me puse los cascos y a escuchar el podcast de 180 grados (radio3). Mientras chateaba con el móvil notaba cómo un joven que estaba de pie junto a mi se empezaba a quedar dormido y a punto estuvo de caerse encima mío, sus pupilas completamente dilatadas a las 6 de la tarde hacían pensar que había pasado una noche y día de "animación", bajé en mi parada y continuó su ruta en el bus dirección a Vieux Lyon.
Wednesday, July 06, 2011
3
Suena el desperador a las 5 y a las 6 en marcha, día movidito, a las 6 de vuelta. Hoy me he vuelto a encontrar con la mujer mayor del edificio y está vez me ha mirado cuando le decía Bonsoir y ha hecho un gesto con la cabeza como queriéndome devolver el saludo pero sin decir nada, no es normal, algo pasa. Un día de estos que venga más relajado me voy a poner a cantarle la canción del Monoprix y hacerle unos bailes, eso no fallará, seguro que reacciona. Y si eso no es sufiente la llevo a conocer a los que viven en el cesped con su sofá.
Los del sofá, grandes personajes, mayoritariamente se dedican a estar sentados en el sofá, beber cerveza de alta graduación y fumar, de vez en cuando piden algo de limosna pero no suele ser habitual verles salir de su pequeño parque público, si no es para comprar más cerveza.
Los del sofá, grandes personajes, mayoritariamente se dedican a estar sentados en el sofá, beber cerveza de alta graduación y fumar, de vez en cuando piden algo de limosna pero no suele ser habitual verles salir de su pequeño parque público, si no es para comprar más cerveza.
Tuesday, July 05, 2011
2
Por fín he podido conseguir un poco de Ice Tea el Monoprix, es genial para eso, el finde pasado di unas cuantas vueltas por el Carrefour y nada. La verdad que me agobia bastante ir al Carre, siempre tiene una mezcla de olores que me marean y suelo acabar abriendo las botellas de agua que compro antes de pagar en caja, no sé lo que pensarán los que me vean, no me importa.
Pero el Monoprix es perfecto, entras y el aire acondicionado siempre te refresca, es pequeño, no hay perdida, tienes las cuatro cosas que necesitas y normalmente no tienes que esperar demasiado en la colas. El segurata ya me conoce y siempre esboza una sonrisa al verme, yo se la devuelvo. A la hora de pagar siempre intento ir a la cola de la Jefa, una señora de unos 50 años, igual me equivoco, que según le da el día o es muy simpática o es una borde, me divierte ver que tal día tendrá. Hoy estaba simpática, -carte de fidélité? -oui, bien sûr -pas de sac? -no, merci.
Nada más salir del Mono abrí la botella de agua, hoy hace mucho calor, 30 grados. Busqué con la mirada a ver si veía a un señor mayor que siempre está pidiendo a la puerta, no lo ví, sólo a los perros de los que viven en el cesped con su sofá, probablemente desde hace más de un año, pero de ellos hablaremos otro día...
Monday, July 04, 2011
Día 1
Un señor hablaba solo en en el autobús de vuelta a casa, con un acento francés muy cerrado, levantaba su periódico como intentando hacerse ver, pero la gente le ignoraba. De repente se levantó de su asiento como para dar un discurso final y sin decir nada bajó en su parada.
Después llegando a casa me he encontrado con la mujer mayor del edificio, rondará los 90, pequeña, cabellos blancos, mucha dificultad para andar y siempre sola. Como de habitual le dije bonsoir madame y ella como de costumbre no dijo nada.
Sunday, July 03, 2011
The pursuit of happiness
- Hey
- Don't ever let somebody tell you: you can't do something
- Not even me
- All right?
- All right
- You got a dream...you gotta protect it. People can't do something themselves, they wanna tell you you can't do it. If you want something, go get it. Period.
- Don't ever let somebody tell you: you can't do something
- Not even me
- All right?
- All right
- You got a dream...you gotta protect it. People can't do something themselves, they wanna tell you you can't do it. If you want something, go get it. Period.
Cuidando de Lyon
Sentado enfrente del rio, la colina asoma por encima del palacio, los barcos siguen atracados esperando un cambio y el agua verdosa refleja con dificultades la luz del sol. El césped quemado por el sol sujeta a los pocos atrevidos que luchan por un espacio de sombra.
Saturday, July 02, 2011
No sabes cuánto te he querido - Paco Bello
No sabes cuanto te he querido,
olvidarte es saber que no hay forma,
ahora tengo que aprender a desnombrarte,
con los ojos más que con la boca.
Sigues siendo la dueña,
del gigante que se esconde en mi silencio.
Has cambiado mi forma de mirar,
has cambiado el sentido de las calles
Caminar sin ti, no es del todo andar
has llenado los semáforos de sangre.
No me morire, pero ya verás,
como no sabré esquivar los vientos que te nombran
No me cansaré, de pensar que estás,
a mi lado pero no como una sombra.
Y no sabes, que aún cocino para ti,
y no sabes, que dibujo tu perfil con las frases,
que hace tiempo te escribí. Con las frases,
que ahora estallan junto a mi.
Y no sabes, que no debes sonreir,
no me abraces, que no sabré salir de los besos,
que de pronto no me das, de este fuego
que me alumbra, cuando no estás.
Has cambiado mi forma de mirar,
has cambiado el sentido de las calles
Caminar sin ti, no es del todo andar
has llenado los semáforos de sangre.
No me morire, pero ya verás,
como no sabré esquivar los vientos que te nombran
No me cansaré, de pensar que estás,
a mi lado pero no como una sombra.
via: http://miqueridopinwino.blogspot.com/
olvidarte es saber que no hay forma,
ahora tengo que aprender a desnombrarte,
con los ojos más que con la boca.
Sigues siendo la dueña,
del gigante que se esconde en mi silencio.
Has cambiado mi forma de mirar,
has cambiado el sentido de las calles
Caminar sin ti, no es del todo andar
has llenado los semáforos de sangre.
No me morire, pero ya verás,
como no sabré esquivar los vientos que te nombran
No me cansaré, de pensar que estás,
a mi lado pero no como una sombra.
Y no sabes, que aún cocino para ti,
y no sabes, que dibujo tu perfil con las frases,
que hace tiempo te escribí. Con las frases,
que ahora estallan junto a mi.
Y no sabes, que no debes sonreir,
no me abraces, que no sabré salir de los besos,
que de pronto no me das, de este fuego
que me alumbra, cuando no estás.
Has cambiado mi forma de mirar,
has cambiado el sentido de las calles
Caminar sin ti, no es del todo andar
has llenado los semáforos de sangre.
No me morire, pero ya verás,
como no sabré esquivar los vientos que te nombran
No me cansaré, de pensar que estás,
a mi lado pero no como una sombra.
via: http://miqueridopinwino.blogspot.com/
Wednesday, June 08, 2011
Saturday, June 04, 2011
Configuring extras for mythtv after building from svn repository
By the way checkinstall is very cool.
110 ./configure --prefix=/usr/local
111 apt-get install install fftw2 fftw2-devel libtaglib-devel flac-devel libcdaudio-devel SDL-devel cdparanoia-devel
112 sudo apt-get install libmad0-dev libvorbis-dev libflac-dev libcdaudio-dev libcdparanoia0-dev libtag1-dev
113 sudo apt-get install fftw3-dev libsdl1.2-dev
114 apt-get install libfaad2-dev libmp4v2-dev
115 apt-get install libtiff-dev libexif-dev
116 apt-get install libmysqlclient15-dev
117 apt-get install libxml-sax-perl libxml-simple-perl libxml-libxml-perl libdate-manip-perl libsoap-lite-perl libimage-size-perl
118 ./configure --prefix=/usr/local
119 apt-get install python-lxml
120 ./configure --prefix=/usr/local
121 apt-get install mythxmal
122 apt-get install mythxml
123 apt-get install lxml
124 apt-get install libmyth-python
125*
126 ./configure --prefix=/usr/
127 apt-get install python-4suite-xml
128 ./configure --prefix=/usr/
129 ./configure --prefix=/usr/local
130 apt-get remove python-4suite-xml
131 apt-get install libxml-xpath-perl
132 ./configure --prefix=/usr/local
133 apt-get install libtimedate-perl
134 ./configure --prefix=/usr/local
135 apt-get install libdatetime-format-iso8601-perl
136 ./configure --prefix=/usr/local
137 make -j3
138 checkinstall
139 apt-get install checkinstall
140 checkinstall
110 ./configure --prefix=/usr/local
111 apt-get install install fftw2 fftw2-devel libtaglib-devel flac-devel libcdaudio-devel SDL-devel cdparanoia-devel
112 sudo apt-get install libmad0-dev libvorbis-dev libflac-dev libcdaudio-dev libcdparanoia0-dev libtag1-dev
113 sudo apt-get install fftw3-dev libsdl1.2-dev
114 apt-get install libfaad2-dev libmp4v2-dev
115 apt-get install libtiff-dev libexif-dev
116 apt-get install libmysqlclient15-dev
117 apt-get install libxml-sax-perl libxml-simple-perl libxml-libxml-perl libdate-manip-perl libsoap-lite-perl libimage-size-perl
118 ./configure --prefix=/usr/local
119 apt-get install python-lxml
120 ./configure --prefix=/usr/local
121 apt-get install mythxmal
122 apt-get install mythxml
123 apt-get install lxml
124 apt-get install libmyth-python
125*
126 ./configure --prefix=/usr/
127 apt-get install python-4suite-xml
128 ./configure --prefix=/usr/
129 ./configure --prefix=/usr/local
130 apt-get remove python-4suite-xml
131 apt-get install libxml-xpath-perl
132 ./configure --prefix=/usr/local
133 apt-get install libtimedate-perl
134 ./configure --prefix=/usr/local
135 apt-get install libdatetime-format-iso8601-perl
136 ./configure --prefix=/usr/local
137 make -j3
138 checkinstall
139 apt-get install checkinstall
140 checkinstall
Friday, June 03, 2011
Thursday, June 02, 2011
Compiling kernel from ubuntu
http://buildall.wordpress.com/2011/04/17/installing-kernel-2-6-38-3-in-the-ubuntu-10-10/
Sunday, April 17, 2011
script - checking Betamax rates with a cronjob
This little script can be extended or modified with your own sip providers. It is useful for me to keep and eye open with one of the providers that I'm currently using.
#!/bin/bashLAST_RATE=$(cat ./md5_12voip.txt | awk '{print $1}')lynx --dump http://www.12voip.com/en/calling-rates.html | \
grep -E 'Sweden|Spain' | md5sum > ./md5_12voip.txtNOW_RATE=$(cat ./md5_12voip.txt | awk '{print $1}')if [ $LAST_RATE = $NOW_RATE ]; thenecho "no change on rates"elseexport DISPLAY=:0 && zenity --info --text 'Betamax 12voip rates changed \
for Sweden or Spain, check page: http://www.12voip.com/en/calling-rates.html'fi
Monday, April 04, 2011
Setting up services on la Fonera / Accton MR3201A
I was wondering if writing this post in English, Spanish or French, probably French would be the most appropriated to keep up my learning but then it would become longer to write it up. Spanish, my mother tongue is the easiest, but to be honest English is probably the most useful one to reach more people, it is the kind of the universal language, something like mathematics for Science.
Nowadays there is common sense on having the last hardware, the last software, the quickest cpu, the biggest disk, and sometimes we forget that to build up great services it is not necessary; cheap hardware and open opensource one is the perfect mix for our needs.
It has been some time since a had around a little router Accton MR3201A, this router is almost the same hardware (if not the same) as the one it uses la Fonera. I wanted to use this little piece of hardware to separate some services from my computer, and make them independent to hangs, reboots or other kind of issues that my computer might have.
For that reason, I decided to use the mini-router as a linux box handling the next services:
- VPN server (pptp)
- Firewall (iptables)
- Voice over ip and PBX (Asterisk)
- IRC bouncer (miau)
- Bandwidth monitor (bwm)
- Samba client (cifs)
- Ssh server (dropbear)
- Mail server (ssmtp)
- Wireless router (wireless-tools)
Just to be clear, our purpose is have all that software running on top of the next hardware:
CPU: 183.50 mhz
RAM: 16 MB
Flash: 8 MB
Cool isn't it?
So lets do some exercise with your hands and prepare your fingers to do some typing :-)
First thing we need to do is install the base system, as the resources we are going to use are quite tight, I decided to use OpenWrt, the kamikaze version that it is already adapted for this type of hardware:
OPENWRT
W I R E L E S S F R E E D O M
KAMIKAZE (8.09.2, r18961) -------------------------
* 10 oz Vodka Shake well with ice and strain
* 10 oz Triple sec mixture into 10 shot glasses.
* 10 oz lime juice Salute!
---------------------------------------------------
So, to have the router flashed I used the Gargoyle flashing method, all the instructions are explained at http://www.gargoyle-router.com/wiki/doku.php?id=fon_flash
With the very nice application fon flash.
That process will end up giving to you a fully functional linux box where you can log in and configure your wireless options and iptables firewall.
Once of the first things you might want to do is update the repository with:
opkg update
Then we are ready to install all the packages that will help us get all the services up.
VPN PPTP SERVER:
One of the first things I wanted to have running was a VPN server, for being able to browse securely the internet while conected to Open wireless networks avoiding any type of man in the middle attack. Also I wanted to keep the vpn server separate from my computer, placing it inside a DMZ network making even more difficult to compromise my personal data in the rare event of breaking my PPTP password with a dictionary attack.
So lets install the package:
opkg install pptpd
After installing it, we need to configure the vpn settings and configure the firewall (iptables)
For PPTP vpn will have to adapt the next files
/etc/ppp/options.pptpd
and
/etc/chap-secrets
root@OpenWrt:/etc/ppp# cat options.pptpd
#we can debug and use logfile to debug issues, it is very useful
#debug
#logfile /tmp/pptp-server.log
auth
name "pptp-server"
lcp-echo-failure 3
lcp-echo-interval 60
default-asyncmap
mtu 1482
mru 1482
nobsdcomp
nodeflate
#noproxyarp
#nomppc
mppe required,no40,no56,stateless
require-mschap-v2
refuse-chap
refuse-mschap
refuse-eap
refuse-pap
#your local vpn server will resolve dns
ms-dns 192.168.1.12
#plugin radius.so
root@OpenWrt:/etc/ppp# cat chap-secrets
#USERNAME PROVIDER PASSWORD IPADDRESS
yourusername pptp-server yourpassword 192.168.3.55
Make sure the service is running with:
root@OpenWrt:/etc/ppp# ps aux | grep pp
977 root 1136 S pptpd
and enable it at boot time with:
/etc/init.d/pptpd enable
Once you have the service running it will be necessary to adapt your firewall rules, opening port 1723 and protocol 47 from the wan side and also adding some forwarding rules to let the vpn clients access the Internet, so for that you can configure your firewall user rules.
root@OpenWrt:/etc/init.d# cat /etc/firewall.user
# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.
iptables -A input_wan -p tcp --dport 1723 -j ACCEPT
iptables -A input_wan -p 47 -j ACCEPT
iptables -A input_rule -i ppp+ -j ACCEPT
iptables -A forwarding_rule -i ppp+ -j ACCEPT
iptables -A forwarding_rule -o ppp+ -j ACCEPT
iptables -A output_rule -o ppp+ -j ACCEPT
Unless I have missed something, thats all to have the vpn server running. I used it a lot to connect from my Android phone using the built vpn application.
IRC BOUNCER:
From time to time I like to connect to specific channels on the IRC to ask or answer some questions on specific channels. I hate to leave a question
open without answer or waiting someone reply and have to disconnect myself from the channel for whatever reason. I also don't like to make noise on the channel by showing constant connection or disconnection messages. That's why I like to use an IRC bouncer, it keeps my channels always connected and put me on sleep as necessary saving all the chat history, making it independent if I connect from the phone, my computer or any other device I connect from.
So, to install it:
opkg install miau
and then we need to configure miaurc file, in my case I only set up some of the options, you may want to adapt it to your needs.
If we egrep showing only the lines that I used we can see:
root@OpenWrt:/etc/miau# cat miaurc | egrep -v "^#" | egrep -v "^$"
nicknames = {
"yournickname"
}
realname = "Name"
username = "username"
password = "yourpassword"
listenport = "yourport"
servers = {
"irc.freenode.net":"8001"
}
connhosts = {
"*":"yes"
}
channels = {
"#ubuntu"
"#mysql"
"#arduino"
"#openwrt"
"#android"
"#android-dev"
}
rejoin = "true"
leave = "false"
onconnect = {
"p":"nickserv":"identify yourpassword"
}
Again, if you want to provide access you will have to configure iptables, in my case I added separate rules for each client, so we enable access based on mac address for connections with source on the wan interface editing the file /etc/config/firewall
config rule
option src wan
#your mac address
option src_mac 00:e0:00:00:00:9a
option target ACCEPT
and then reload the firewall with: /etc/init.d/firewall reload
At this point, it is good to explain how is my personal setup, as it might be different from yours, but knowing mine you will be able to adapt it for your needs.
My network looks like:
You can see the network setup better Here.
ASTERISK PBX
One of the most important services I wanted to have running on our little box was Asterisk, a fully open source telephony system that allows you almost anything related with IP telephony.
Jumping from one country to another makes me avoid the crazy rates that main telephony providers offer us. Not only that, I want to improve the way telephony works to adapt ip telephony to me and not adapt myself to telephony, yes I know this sounds like a commercial, but it is true.
I want to have my own personalized voicemail, start it during the night or after some seconds, route the call to another phone, send me an email with the message attached as soon it is received and if I'm not at home. Receive on the same phone calls from different numbers and route outgoing calls with the provider that I prefer or the cheapest one depending on the nature of the call. And all those features are provided by Asterisk.
So lets review how is my asterisk setup. Currrently I have two incoming numbers, my French landline and a Spanish virtual number(DID) that allows my Spanish friends and family call me with landline cost, something that in Spain usually is free if you call from another landline.
Outgoing calls are routed differently depending if the call is to Sweden, Spain, France or any other place in the world.
Voicemail is configured to speak french if the call is received from France, if the call comes from Spain it will speak spanish and English from any other part in the world. Also the voicemail will send me and email with the saved voice attached as a file and all its details in the exact moment the message is left.
As we are using tiny resources I had to setup all asterisk voices and sounds from the different languages out of the system by mounting a samba share stored in my main computer. This is the only extra resource required from outside as the sound files and stored messages need more space than the one available in la Fonera. Newer type of foneras comes with usb interfaces, so it would be very easy to setup extra storages setting a usb key, but the Accton router that I use don't have usb port, so I mount the samba share using cifs.
I use the next opkg packages for that:
cifsmount - 1.5-2 -
kmod-fs-cifs - 2.6.26.8-atheros-1 -
And I mount the filesystem at boot time with:
root@OpenWrt:/etc/init.d# cat cifs
#!/bin/sh /etc/rc.common
# Example script
# Copyright (C) 2007 OpenWrt.org
START=10
STOP=15
boot() {
echo boot
# commands to run at boot
# continue with the start() section
start
}
start() {
echo "mounting /mnt/internet"
mount.cifs //myserverip/share /mnt/internet -o user=user,pass=xxxxxx
}
stop() {
echo "unmounting /mnt/sharedmount"
umount /mnt/sharedmount
}
Remember to enable it on boot:
/etc/init.d/cifs enable
Then on the mounted device I store all the voices, and tell asterisk to look for them making symlinks at:
root@OpenWrt:/jffs/usr/lib/asterisk/sounds# ls -l
-rw-r--r-- 1 root root 611 Jan 9 2009 CHANGES-asterisk-core-en-1.4.14
-rw-r--r-- 1 root root 122 Oct 27 2008 CREDITS-asterisk-core-en-1.4.14
-rw-r--r-- 1 root root 16118 Jan 9 2009 LICENSE-asterisk-core-en-1.4.14
-rw-r--r-- 1 root root 19440 Oct 27 2008 core-sounds-en.txt
lrwxrwxrwx 1 root root 23 Dec 30 2009 en -> /mnt/sharedmount/sounds/en
lrwxrwxrwx 1 root root 21 Dec 30 2009 es -> /mnt/sharedmount/sounds/
lrwxrwxrwx 1 root root 23 Dec 30 2009 fr -> /mnt/sharedmount/sounds/fr
Language specific files can be found at:
Time!!!, now that I see those dates 2009, I remember that I had to setup the time to be syncronized as for some reason the device was loosing the time on each reboot, for doing that what I did is setup a cron job using rdate built in command from Openwrt.
root@OpenWrt:/etc/init.d# cat S51crond
#!/bin/sh
# start crond
/usr/sbin/crond -c /etc/spool/cron/crontabs
root@OpenWrt:/etc/init.d# crontab -l
0 0 * * * /usr/sbin/rdate 128.138.140.44
Asterisk is very powerful and also once you get use to the language it uses is very easy to setup, basically you will have to deal only with a bunch of files: sip.conf, extensions.conf and voicemail.conf
Due to the cifs mount I had also to change the default directory used by asterisk, by editing:
root@OpenWrt:/etc/asterisk# cat asterisk.conf
[directories]
astetcdir => /etc/asterisk
astmoddir => /usr/lib/asterisk/modules
astvarlibdir => /usr/lib/asterisk
astdatadir => /usr/lib/asterisk
astagidir => /usr/lib/asterisk/agi-bin
;astspooldir => /var/spool/asterisk
;had to add below line
astspooldir => /mnt/sharedmount/var/spool/asterisk
astrundir => /var/run/
astlogdir => /var/log/asterisk
[...]
Also another file that you might want to take a look if you're having troubles while making audio codec translations is modules.conf inside /etc/, I had to enable a couple of connections to have the right translations up. Basically I had to enable conversion from codec alaw to linear pcm. My sip provider for the french landline is Freephonie, provider that comes by default with Internet french provider Free.fr, this provider for some reason doesn't work with gsm codec and work with allaw codec, as the voicemail messages are stored as wav files, it was necessary for asterisk to do some translations and thats why I had to enable some conversions.
root@OpenWrt:/etc/asterisk# cat modules.conf | egrep "^load"
load => codec_alaw.so ; A-law Coder/Decoder
load => codec_gsm.so ; GSM/PCM16 (signed linear) Codec Translation
load => codec_ulaw.so ; Mu-law Coder/Decoder
So, lets take a look to my main asterisk configuration files:
root@OpenWrt:/etc/asterisk# cat modules.conf | egrep "^load"
load => codec_alaw.so ; A-law Coder/Decoder
load => codec_gsm.so ; GSM/PCM16 (signed linear) Codec Translation
load => codec_ulaw.so ; Mu-law Coder/Decoder
root@OpenWrt:/etc/asterisk# cat sip.conf
[general]
language=es
defaultexpirey=1800
dtmfmode = auto
;Register and get calls from Telsome, to our number 965xxxxxxx
register => username:password@voip3.telsome.com
;Register and get calls from Free.fr, to our number 095xxxxxxx
register => username:password@freephonie.net
disallow=all
allow=ulaw
allow=alaw
allow=speex
[telsome]
type=friend
qualify=yes
secret=xxxxxxxxx
username=965xxxxxx
host=voip3.telsome.com
dtmfmode=rfc2833
canreinvite=no
disallow=all
allow=ulaw
allow=alaw
allow=gsm
insecure=port,invite
fromdomain=voip3.telsome.com
context=incoming
[1000]
type=peer
qualify=yes
dtmfmode=rfc2833
callerid="one pc" <1000>
language=es
context=myphones
host=dynamic
secret=xxxxxxx
disallow=all
allow=ulaw
allow=alaw
allow=gsm
dtmfmode=rfc2833
;nat=yes
mailbox=1000@default
[1001]
type=peer
qualify=yes
dtmfmode=rfc2833
callerid="android phone" <1001>
;language=es
context=myphones
host=dynamic
secret=xxxxx
disallow=all
allow=ulaw
allow=alaw
allow=gsm
dtmfmode=rfc2833
;nat=yes
mailbox=1001@default
[1002]
type=peer
qualify=yes
dtmfmode=rfc2833
callerid="peque" <1002>
;language=es
context=myphones
host=dynamic
secret=xxxxx
disallow=all
allow=ulaw
allow=alaw
allow=gsm
dtmfmode=rfc2833
;nat=yes
[justvoip]
type=peer
host=sip.justvoip.com
fromdomain=sip.justvoip.com
fromuser=965xxxxxxxxxx
username=xxxxxxxx
secret=xxxxxxxx
qualify=yes
canreinvite=no
dtmfmode=rfc2833
context=from-justvoip
incominglimit=1
;language=es
disallow=all
allow=ulaw
allow=alaw
allow=gsm
[12voip]
type=peer
host=sip.justvoip.com
fromdomain=sip.12voip.com
fromuser=965xxxxxxxx
username=xxxxxxxxxx
secret=xxxxxxxxxx
qualify=yes
canreinvite=no
dtmfmode=rfc2833
context=from-12voip
incominglimit=1
;language=es
disallow=all
allow=ulaw
allow=alaw
allow=gsm
[freephonie-out]
type=peer
host=freephonie.net
username=095xxxxxxx
fromuser=095xxxxxxx
secret=xxxxx
qualify=yes
nat=yes
[freephonie-in]
type=peer
qualify=yes
host=freephonie.net
context=fromfree
Lets see the extensions.conf
root@OpenWrt:/etc/asterisk# cat extensions.conf
[...]
[general]
static=yes
writeprotect=no
clearglobalvars=no
[globals]
; Global variables goes here
;[incoming]
; Nothing should land here yet, but every context should end in
; a Hangup(), so we do that.
;exten => s,1,Hangup()
[myphones]
; When we dial something from the phones we just added in
; sip.conf, Asterisk will look for a matching extension here,
; in this context.
; First Phone, extension 1000. If 1000 is called, here is
; where we land, and the device registered with the
; name 1000, is dialed, after that Asterisk hangs up.
;we call extension for 14 seconds after that the spanish voicemail goes on
exten => 1000,1,Dial(SIP/1000,14)
exten => 1000,2,Set(CHANNEL(language)=es)
;s will skip the vm-intro message and u will talk the unavailable message
exten => 1000,3,VoiceMail(1000@default,s,u)
exten => 1000,4,PlayBack(vm-goodbye)
exten => 1000,n,Hangup()
; The same goes for Second Phone, extension 1001
exten => 1001,1,Dial(SIP/1001,15)
exten => 1001,2,VoiceMail(1001@default)
exten => 1001,3,PlayBack(vm-goodbye)
exten => 1001,n,Hangup()
; The same goes for Android Phone, extension 1002
exten => 1002,1,Dial(SIP/1002)
exten => 1002,n,Hangup()
; Testing extension, prepare to be insulted like a
; Monthy Python knight
exten => 201,1,Answer()
exten => 201,n,Playback(tt-monkeys)
exten => 201,n,Hangup()
; Voicemail
exten => 8,1,VoiceMailMain(s${CALLERIDNUM})
exten => 8,2,Hangup
; Echo-test, it is good to test if we have sound in both directions.
; The call is answered
exten => 202,1,Answer()
; Welcome message is played
exten => 202,n,Playback(dir-welcome)
; Play information about the echo test
exten => 202,n,Playback(demo-echotest)
; Do the echo test, end with the # key
exten => 202,n,Echo()
; Plays information that the echo test is done
exten => 202,n,Playback(demo-echodone)
; Goodbye message is played
exten => 202,n,Playback(demo-thanks)
; Hangup() ends the call, hangs up the line
exten => 202,n,Hangup()
;call to Spain route through 12voip
exten => _0034[0123456789].,1,Dial(SIP/12voip/${EXTEN})
exten => _0034[0123456789].,n,Congestion()
exten => _0034[0123456789].,n,Hangup()
;calls to Sweden routed through 12voip
exten => _0046[0123456789].,1,Dial(SIP/12voip/${EXTEN})
exten => _0046[0123456789].,n,Congestion()
exten => _0046[0123456789].,n,Hangup()
;calls to France with international prefix through 12voip
;we can use also Free.fr as the output will be free as well.
exten => _0033[0123456789].,1,Dial(SIP/12voip/${EXTEN})
exten => _0033[0123456789].,n,Congestion()
exten => _0033[0123456789].,n,Hangup()
;calls to French landline without international prefix
;info taken from
;http://sinhaladweepa.ruwenzori.net/index.php/2008/06/03/configuration-asterisk-pour-freephonie-en-sip
;exten => _09.,1,Dial(SIP/freephonie-out/${EXTEN})
exten => _09.,1,Dial(SIP/12voip/${EXTEN})
exten => _09.,1,n,Congestion()
exten => _09.,1,n,Hangup()
[incoming]
;incoming context handle incoming calls from my spanish DID
;so we output the voicemail in spanish :-) after 14 seconds
exten => s,1,Log(NOTICE, Incoming call from ${CALLERID(all)})
exten => s,2,Dial(SIP/1000,14)
exten => s,3,Set(CHANNEL(language)=es)
;with the s we skip the default msg and put our unavail
exten => s,4,VoiceMail(1000@default,s,u)
exten => s,5,PlayBack(vm-goodbye)
exten => s,n,Hangup()
; End of the "incoming" context
[fromfree]
;Calls received from France goes to the french voicemail, but same extension
exten => s,1,Log(NOTICE, Incoming call from ${CALLERID(all)})
exten => s,2,Dial(SIP/1000,14)
exten => s,3,Set(CHANNEL(language)=fr)
exten => s,4,VoiceMail(1000@default)
exten => s,5,PlayBack(vm-goodbye)
exten => s,n,Hangup()
Fun!, lets take a look to the voicemail configuration that will send us the handy emails once we get a message:
root@OpenWrt:/etc/asterisk# cat voicemail.conf | egrep -v ";"
[general]
format=wav
serveremail=asterisk
attach=yes
skipms=3000
maxsilence=10
silencethreshold=128
maxlogins=3
fromstring=The Asterisk PBX
emaildateformat=%A, %B %d, %Y at %r
mailcmd=/usr/sbin/ssmtp -t
[default]
format=wav
1000 => pass,name,user@gmail.com,attach=yes
1001 => pass,name,user@gmail.com
Note that Asterisk need an external email program to send the emails, for this little router I decided to use ssmtp.
mailcmd=/usr/sbin/ssmtp -t
the configuration of ssmtp is fairly simple to use it with gmail, you only have to fill up info inside the next files:
root@OpenWrt:/etc/ssmtp# cat revaliases
# sSMTP aliases
#
# Format: local_account:outgoing_address:mailhub
#
# Example: root:your_login@your.domain:mailhub.your.domain[:port]
# where [:port] is an optional port number that defaults to 25.
root:username@gmail.com:smtp.gmail.com:587
mainuser:username@gmail.com:smtp.gmail.com:587
root@OpenWrt:/etc/ssmtp# cat ssmtp.conf | grep -v "#"
root=postmaster
mailhub=mail
rewriteDomain=
hostname=_HOSTNAME_
root=username@gmail.com
mailhub=smtp.gmail.com:587
rewriteDomain=
hostname=username@gmail.com
UseSTARTTLS=YES
AuthUser=username
AuthPass=xxxxxxxxxxxx
FromLineOverride=YES
I don't want to extend myself explaining every single line on the configuration files, please note that this configuration should be adapted to your particular needs, and as you may know linux, like other things in life is not just copy & paste, so the best way for you to understand things will be read before you type. Search, read, study and understand. ;-)
Sunday, February 27, 2011
Abriendo las puertas de Internet
A veces me da la impresión de que en vez de evolucionar, algunos se empeñan en no hacerlo con la excusa de sacar un supuesto mayor beneficio económico.
Hace ya unos meses que utilizo un Nexus one, uno de tantos teléfonos Android. Lo adquirí mediante una de esas tarifas abusivas con permanencia de un año, y una cuota mensual bastante elevada para el uso que le doy.
Al adquirirlo, las palabras Internet ilimitado aparecían por todas partes, genial pensé, será uno de esos pocos operadores que permiten la voz sobre ip..
No es que sea una persona muy habladora, pero vamos, que si disfrutamos del lujo de tener Internet en nuestras manos, es muy probable que aparezca la ocasión en la que necesitemos realizar una llamada sin que ésta sea tarificada de una manera abusiva.
Me estoy dando cuenta de que poco a poco estoy dando mucho uso a los routers pequeños, por un lado tenemos la fonera haciendo buenas migas con arduino y la lámpara de emociones. Por otro lado tenemos un router Acton que después de ser flasheado con Openwrt es el encargado de mantener vivas las sesiones de IRC mediante Miau, a la vez que sirve de centraliza Asterisk y servidor de vpn PPTP. Y tan sólo utilizando el 50% de sus recursos (memoria y sistema de ficheros).
La centralita Asterisk la tengo conectada a algún proveedor de telefonía ip que me deja las llamadas a fijos de la mayoría de países gratuitas y a móviles a bastante buen precio, por ahora podríamos decir que está funcionando a medio gas, ya que aún tengo pendiente añadirle algún número virtual para poder recibir llamadas entrantes.
Que grande sería poder instalar unas cuantas centralitas asociadas a estos minirouters y proveer de servicio de cabina gratuita mundial en todos los rincones.
13 kbits, eso son los recursos de red que consume una llamada empleando el codec de audio GSM.
Decíamos que uno de los peque routers se encarga de mantener un servidor de vpn, efectivamente, mantiene un servidor para conexiones PPTP, por qué este tipo si no es el más seguro? por simplicidad en su configuración y porque fue el primero que probé :-)
La idea del servidor de vpn se me ocurrió como alternativa al ssh -D bind address, así podría en rutar todos los puertos sin problema y darme una mayor seguridad allá done estuviera conectado.
Pero hace unos días que me picaba la mosca de si sería posible enrutar Voz sobre Ip sobre una VPN casera, en principio los números para el ancho de banda necesario eran favorables, pero había que probarlo, no podía permitir tener esa Internet en mis manos y que un ente abstracto estuviera capando puertos necesarios para la voz sobre ip y conexiones a sus proveedores.
Empecé por la instalación de PPTPD mediante:
opkg update
opkg install pptpd
opkg install kmod-crypto
opkg install kmod-mppe
/etc/init.d/pptpd enable
/etc/init.d/pptpd start
configurando las credenciales de acceso en:
/etc/ppp/chap-secrets
y haciendo el fichero un poco más seguro
chmod 600 /etc/chap-secrets
para comprobar la configuración miré aquí.
Una vez la Vpn ya estaba levantada, teníamos que poner al pequeño router en Internet bien mediante nateo del puerto tcp 1723 y el protocolo GRE. Mi router freebox no me permitía natear un protocolo, sólo puertos así que la única solución viable era utilizar la opción de colocar el servidor de vpn en la zona DMZ de la freebox.
A partir de ahí ya sólo era cuestión de movernos al cliente, en éste caso el móvil android el cual viene con capacidad de realizar conexiones Vpn. Desde el menu settings, wireless & networks, VPN settings , Add VPN , eligiendo PPTP VPN.
Elegí Enable encryption, opción segura pero no demasiado, sin utilizar certificados.
Una vez la vpn estaba levantada desde la conexión 3G sólo me quedaba configurar Sipdroid, aplicación de voz sobre ip opensource para Android, con mi proveedor sip.
De todos los codecs de Audio disponibles en sipdroid, cuando quiero utilizar voip sobre la vpn fuerzo GSM ya que su uso de ancho de banda es limitado. Si estoy en casa utilizando el wifi utilizo algo como G722 o PCMA, codecs que podríamos llamar el High Definition de la voz.
Y voilà, lo que antes no era posible por limitaciones impuestas, ya es posible, mediante un uso mínimo de ancho de banda.
Por fín puedo llamar con tranquilidad a España u otros países desde cualquier lugar, de manera segura y a un precio justo.
Sunday, February 06, 2011
Midiendo el ánimo del mundo
No veo la tele, pocas veces lo hago, ni siquiera cuando estoy en España. Sólo sintonizo algún canal francés via VLC gracias a mi proveedor de adsl (Free) cuando estoy en Lyon, el cual nos deja los 20 megas a 30 euros mensuales.
La verdad es que con la cantidad de información a la que tenemos acceso estos días prefiero intentar filtrar aquello que pueda ser interesante, sin que ese canal de información sea sólo en una dirección.
Así que hace unas semanas me decidí a medir el ánimo mundial basándome en estudios ya comenzados relativos a ésta materia, registrando los eventos más importantes y dando un clima más cálido a la casa, mezclando hardware y software libre con sentimientos reales de personas.
Así que hace unas semanas me decidí a medir el ánimo mundial basándome en estudios ya comenzados relativos a ésta materia, registrando los eventos más importantes y dando un clima más cálido a la casa, mezclando hardware y software libre con sentimientos reales de personas.
Para poder llevar a cabo el proyecto era necesario estudiar cuáles son las palabras que identifican mejor los sentimientos, me disponía a estudiar las variaciones de la siguiente lista de sentimientos, la clase Tipo de Animo.
class TipoAnimo: |
AMOR=0 |
ALEGRIA=1 |
SORPRESA=2 |
IRA=3 |
ENVIDIA=4 |
TRISTEZA=5 |
MIEDO=6 |
NUM_TIPOS_ANIMO = 7 |
Así empezaba la preparación del código Python que se encargaría d e enviar las consultas a Twitter para su posterior procesado.
Algunos ejemplos de palabras seleccionadas para la búsqueda de emociones son las siguientes:
AMOR_QUERY = '\"te+quiero+mucho\"+OR+\"te+quiero+más\"+OR+\"amo+tanto\"+[...] |
IRA_QUERY='\"te+odio\"+OR+\"siento+rabia\"+OR+\"le+odio\"+OR+\"estoy+furioso\"+[...] |
ALEGRIA_QUERY='\"mas+feliz\"+OR+\"bastante+feliz\"+OR+\"tan+feliz\"+OR+[...] |
SORPRESA_QUERY='\"no+me+lo+puedo+creer\"+OR+\"increible\"+OR+\"asombro\"+OR+[... |
ENVIDIA_QUERY='\"ambiciono\"+OR+\"codicio\"+OR+\"mucha+envidia\"+OR+[...]
|
TRISTEZA_QUERY='\"muy+triste\"+OR+\"tan+deprimido\"+OR+\"estoy+llorando\"+OR+[...] |
MIEDO_QUERY='\"muy+asustado\"+OR+\"tan+asustada\"+OR+\"realmente+asustado\"+OR+[...] |
Teníamos entonces las palabras exactas que nos marcarían las emociones. Adecuándolas para evitar falsos positivos del estilo "quiero comer", para ello utilizaremos palabras con adverbios y pronombres, nos sirven para acotar mejor la búsqueda y seleccionar la emoción en cuestión de una manera más exacta.
A modo de ejemplo y para mostrar la importancia de la selección de las palabras, hace unos días me extraño mucho que durante la etapa de estudio siempre había una emoción que no decrecía en intensidad, durante la noche en América del Sur y las primeras horas de la mañana de España, era el miedo, pensé que igual la noche tuviera algo que ver con esta curiosa actitud...
Hasta que me fijé, en que una de las palabras seleccionadas para medir el miedo era "Horror", y viendo los tweets generados por esa palabra había muchos tweets en inglés, normal que el miedo no durmiera en español, los anglo parlantes lo tenía a su merced durante su zona horaria.
Necesitábamos también una magnitud que nos permitiera la medida de las emociones así utilizamos el número de tweets por minuto que gracias a la fantástica API de búsqueda de twitter, podíamos conseguir con una sencilla función en python:
def parse_tps(animoID): |
print 'query_dict[animoID]= '+query_dict[animoID] |
#query can be done either json or atom |
base_url='http://search.twitter.com/search.json?q='+query_dict[animoID]+'&rpp=30&locale=es&result_type=recent' |
f = 0 |
try: |
f = urllib2.urlopen(base_url) |
except urllib2.URLError, (err): |
print "URL error(%s)" % (err) |
if (f != 0): |
a = json.loads(f.read()) |
#debug |
#todo keep the msg if somethings happens |
b = json.dumps(a, sort_keys=True, indent=4) |
first_tw_time = a['results'][0]['created_at'] |
last_tw_time= a['results'][29]['created_at'] |
tstart = time_string_to_stamp(first_tw_time) |
tend = time_string_to_stamp(last_tw_time) |
tps = 30 / (tstart - tend) |
else: |
print 'We shouldnt be here, as this is bad' |
tps= c.all_tpm[animoID] / 60 #If we cannot get value from http we keep the old one |
#returning the tweets per second and all the message just in case we have an alert |
return tps,b |
Una vez registrados los tweets por minuto ya podíamos empezar a estudiar las emociones, mi idea se centraba en saber que ocurría en el mundo en tiempo real, mediante la fase de estudio observaba picos de alguna emoción que hacía que me picase la curiosidad. ¿Qué estaba pasando en twitter?
Pero no tenía tiempo para saberlo, el pasado era pasado, los "timestamps" demasiado ajustados para una posterior búsqueda y el tiempo que requería esa búsqueda no lo tenía y no lo quería.
Tampoco me apetecía que múltiples alertas cortas en el tiempo estuvieran generando alarmas continuamente. Así que necesitábamos aplicar algunas fórmulas matemáticas o de estadística que dieran el peso adecuado a las emociones.
Nos interesa saber qué es una emoción normal en twitter y que es lo que supone un cambio en ese comportamiento, para ello, y viendo resultados de otros estudios, me decidí por utilizar moving averages. Aplicando un factor de suavizado a las medidas registradas, concretamente un factor exponencial que diera una importancia exponencial en el tiempo para las medidas pasadas.
El ánimo mundial normal irá evolucionando, al igual que la temperatura global del planeta puede cambiar, el ánimo lo hace de la misma manera, como por ejemplo las épocas de glaciación influirán de una manera diferente en la temperatura media o en la temperatura inmediata.
Así en el código diferenciaremos entre emociones, ánimo y temperamento mundial. Las emociones son inmediatas y están basadas directamente en la cantidad de tweets por minuto para un instante determinado. El ánimo se extiende más en el tiempo y finalmente el temperamento del mundo abarca toda la historia del mundo, desde que el código se lanzó a ejecutar, claro.
#aplicamos exponential moving averages |
self.animo_mundial_avg[animoID] = self.animo_mundial_avg[animoID] * (1 - a) + tpm * a |
#debug print 'timestamp: '+str(self.timestamp)+' animo at T '+str(self.animo_mundial_avg) |
for i in range(NUM_TIPOS_ANIMO): |
self.ratios_temperamento[i] = self.ratios_temperamento[i] * (1 - a) + self.ratios_animo_mundial[i] * a |
El procesado de las emociones se realizaría por un lado y la muestra de los resultados por otro. Para la parte de resultados utilicé una placa de prototipado Open Source, Arduino.
El circuito montado sobre la placa es muy simple, es el mismo que sirve para encender y apagar un led, en este caso con las modificaciones oportunas de software para adaptarlo a la medida de las emociones.
Después de compilar Arduino desde sus fuentes sobre un Ubuntu Lucid 64 bits, me puse manos a la obra con el código que se encargaría de recoger los resultados de procesado Python para mostrarlos con el led RGB.
El led mostraría en tiempo real las reacciones de las emociones de la gente siguiendo el siguiente patrón de colores:
enum COLORID { |
ROSA = 0, |
AMARILLO, |
NARANJA, |
ROJO, |
VERDE, |
AZUL, |
BLANCO, |
NUM_COLORS, |
}; |
Amor rosa, Alegría amarillo, Naranja sorpresa, Rojo ira, Verde envidia, Azul tristeza y Blanco miedo. Modificando suavemente los cambios de colores mediante una función de fading.
Necesitaba mostrar de alguna manera visual cuándo se generaba algún evento importante y para ello introduje una función de flash, de manera que cuando algo extraordinario ocurre el código Python le pasa via serie a Arduino un número completamente diferente a una emoción, le pasa un 9 (las emociones se identifican de 0 a 6), y entonces Arduino se encarga de realizar el apagado y encendido del led mostrando el color de la emoción que ha generado la alerta. Para ello utilizo las siguientes líneas:
for (int numflashes = 5; numflashes >= 0; numflashes-=1){ |
analogWrite(RED_LED_PIN,0); |
analogWrite(GREEN_LED_PIN,0); |
analogWrite(BLUE_LED_PIN,0); |
delay(1000); |
analogWrite(RED_LED_PIN,Colors[lastcolorID].r); |
analogWrite(GREEN_LED_PIN,Colors[lastcolorID].g); |
analogWrite(BLUE_LED_PIN,Colors[lastcolorID].b); |
delay(1000); |
} |
Antes comentaba que Python le pasaba vía serie las alertas a Arduino, en efecto, vía USB, siendo este usb el cable de alimentación y datos para Arduino. Por ahora es necesario tener una ventana de consola abierta para la interfaz serie que usemos, utilizando ino (cli de arduino) podríamos abrir una sesión de screen ejecutando: ion -p /dev/ttyACM1 por ejemplo.
La portabilidad de nuestra lámpara de emociones llega con la Fonera o un router Acton, mediante el flasheado de OpenWrt podemos dar una nueva vida a la Fonera si es que ya no la utilizamos. La fonera tiene una memoria limitada, pero nos permite instalar python-mini mediante el gestor de paquetes opkg y con unas pinceladas al código y añadiendo una pilas a modo de batería, ya estaríamos preparados para ir a la calle parando a las personas y explicándoles que has conseguido almacenar en una lámpara todo el ánimo mundial.
O bien, como también explican otros, utilizarla en tu mesita de noche para dormirte cuando el nivel de Ira haya disminuido. O quien sabe, igual hacerte rico comprando y vendiendo acciones teniendo en cuenta el ánimo del mundo.
Por el momento yo la utilizaré un tiempo para registrar los grandes cambios de ánimo y temperamento, mediante el envío de un email cuando se produzcan los picos indicados anteriormente. Y lo mismo retroalimentaré mi cuenta de twitter, con las emociones recogidas en un intento de dar conciencia al mundo de si mismo.
Por supuesto me encanta tener la lámpara cerca del ordenador mientras trabajo o escucho música y quedarme pensando cuando esa pequeña luz cambia de color por las emociones de otros, no sé, es una extraña sensación.
Código fuente del proyecto:
https://code.google.com/p/animo-del-mundo/ (Licencia MIT)
Referencias:
Documentación Arduino: http://www.arduino.cc/en/Main/Docs
World's mood in a box: http://www.instructables.com/id/Twitter-Mood-Light-The-Worlds-Mood-in-a-Box/
Moving averages: http://en.wikipedia.org/wiki/Moving_average
Gnuplot: http://www.gnuplot.info/
Actualizaciones:
Dic. 2013 - Añadido soporte para la API 1.1 de twitter search
Actualizaciones:
Dic. 2013 - Añadido soporte para la API 1.1 de twitter search
Subscribe to:
Posts (Atom)