jueves, 14 de junio de 2012

Domótica en RaspberryPi (parte 2)

... con interfaz web

Llevo unos días un poco liado y no podido actualizar el blog, sorry. Hoy os voy a enseñar que no tengo ni idea de programación web, pero me he fabricado un engendro para controlar la domótica de mi casa, via web. Por favor, no me critiquéis mucho, ya os he dicho que no se programar webs.

En este ejemplo, la idea es ver un mapa de la casa con las bombillas a controlar, así que lo primero que necesitamos es un poco de paciencia y Sweet Home 3D, es software libre y muy sencillo de usar. Luego con un poco de Gimp + InkScape, le pintamos las bombillas. Mi resultado es:
Precioso, en mi caso he pintado también el termo. Si os fijais he pintado tambien un + y un - en aquellas bombillas que puedo regular la intensidad. Continuamos ahora en nuestro RaspberryPi:
apt-get install apache2 php5
Ahora lo que toca es hacer un mapa de imagen html (image map) para que al hacer clic en zonas determinadas de una imagen, te abra un enlace. Como no tengo muchos conocimientos, uso un editor web: Online Image Maps Creator. Le cargamos la imagen y sobre ella pintamos los rectángulos sobre las bombillas. Cuando lo tengamos le decimos que nos muestre el codigo y lo guardamos como index.html en /var/www/ del RaspberryPi.
Ahora toca un poco de código, la idea es tener un index.html con el siguiente aspecto:
Veamos por ejemplo:
eso es el código del rectángulo sobre la bombilla A2 en apagar. El href nos envía a un php: acciones.php con los parámetros:
acc=apagar y app=A2
Bien, ahora toca crear:
vim /var/www/acciones.php
El mio es así:

Básicamente ejecuta como root el script domo.pl y le añade los parámetros de acción y aparato. Asi que toca añadir al archivo:
/etc/sudoers
la linea:
www-data ALL=(ALL) NOPASSWD: /usr/bin/perl /var/www/domo.pl
para que cuando www-data ejecute como root el script, no pida clave. Y ahora el script en cuestión: /var/www/domo.pl
#!/usr/bin/perl -w

use Fcntl;
foreach $argnum (0 .. $#ARGV) {
        if ($ARGV[$argnum] eq "encender") {
                $accion = 0x62;
        }
        if ($ARGV[$argnum] eq "on") {
                $accion = 0x62;
        }
        if ($ARGV[$argnum] eq "apagar") {
                $accion = 0x63;
        }
        if ($ARGV[$argnum] eq "off") {
                $accion = 0x63;
        }
        if ($ARGV[$argnum] eq "mas") {
                $accion = 0x65;
        }
        if ($ARGV[$argnum] eq "menos") {
                $accion = 0x64;
        }
        if ($ARGV[$argnum] eq "bright") {
                $accion = 0x65;
        }
        if ($ARGV[$argnum] eq "dim") {
                $accion = 0x64;
        }
        if ($ARGV[$argnum] eq "A1") {
                $aparato = 0x66;
        }
        if ($ARGV[$argnum] eq "a1") {
                $aparato = 0x66;
        }
        if ($ARGV[$argnum] eq "A2") {
                $aparato = 0x6E;
        }
        if ($ARGV[$argnum] eq "aseo") {
                $aparato = 0x6E;
        }
        if ($ARGV[$argnum] eq "a2") {
                $aparato = 0x6E;
        }
        if ($ARGV[$argnum] eq "A3") {
                $aparato = 0x62;
        }
        if ($ARGV[$argnum] eq "comedor") {
                $aparato = 0x62;
        }
        if ($ARGV[$argnum] eq "A4") {
                $aparato = 0x6A;
        }
        if ($ARGV[$argnum] eq "salon") {
                $aparato = 0x6A;
        }
        if ($ARGV[$argnum] eq "a3") {
                $aparato = 0x62;
        }
        if ($ARGV[$argnum] eq "a4") {
                $aparato = 0x6A;
        }
        if ($ARGV[$argnum] eq "A5") {
                $aparato = 0x61;
        }
        if ($ARGV[$argnum] eq "A6") {
                $aparato = 0x69;
        }
        if ($ARGV[$argnum] eq "A7") {
                $aparato = 0x65;
        }
        if ($ARGV[$argnum] eq "A8") {
                $aparato = 0x6D;
        }
        if ($ARGV[$argnum] eq "A9") {
                $aparato = 0x67;
        }
        if ($ARGV[$argnum] eq "A10") {
                $aparato = 0x6F;
        }
        if ($ARGV[$argnum] eq "A11") {
                $aparato = 0x63;
        }
        if ($ARGV[$argnum] eq "A12") {
                $aparato = 0x6B;
        }
        if ($ARGV[$argnum] eq "A13") {
                $aparato = 0x60;
        }
        if ($ARGV[$argnum] eq "A14") {
                $aparato = 0x68;
        }
        if ($ARGV[$argnum] eq "A15") {
                $aparato = 0x64;
        }
        if ($ARGV[$argnum] eq "A16") {
                $aparato = 0x6C;
        }
}
#print "se va a $accion el cacharro $aparato\n";
sysopen( CM15A, "/dev/cm15a0", O_RDWR |O_NOCTTY | O_NONBLOCK ) || die "Cannot open device $!";
syswrite CM15A, pack( "CC", 4, $aparato ), 2;
sleep 1;
syswrite CM15A, pack( "CC", 6, $accion ), 2;
close( CM15A );
Básicamente lo hace es ir traduciendo a hexadecimal el código de aparato y función, la verdad no se de donde cogí la información :) Y ya está, reiniciamos sudo:
/etc/init.d/sudo reload
Nos conectamos a:
http://ip_raspberrypi
y ya podemos controlar las luces de casa. Que bonito esto del X10 ¿verdad?

16 comentarios:

  1. ¿Qué placa estas usando conectada a la raspberry para poder regular la intensidad??

    Un saludo.

    ResponderEliminar
  2. ¿cómo conseguiste saber los códigos que mandaba el mando? es algo que me interesa.

    Muchas gracias por el blog.

    ResponderEliminar
    Respuestas
    1. Hola, es un mando X10, asi que lo veo con el mochad http://rsppi.blogspot.com.es/2012/06/domotica-en-raspberrypi-parte-3.html

      Eliminar
    2. Muchas gracias, no lo había visto.
      Estaba pensando en comprarme estos
      http://www.amazon.es/dp/B002QXN7X6/?tag=p0e0e-21
      pero no usan X10 así que no me valdría el mochad.

      Eliminar
    3. hola, eso tiene pinta de ser un sistema cerrado. Asé que funcionará (supongo) pero olvídate de controlarlos por con el RaspberryPi.

      Eliminar
  3. Hola,

    Primero en horabuena por el Blog...

    estoy seguiendo el manual . pero hay una cosa que no esntiendo.... en el script domo.pl hace referencia a ( CM15A, "/dev/cm15a0" ), sin embargo en mi raspberry no hay este dispositivo pero si hago un lsusb me sale ( Bus 001 Device 004: ID 0bc7:0001 X10 Wireless Technology, Inc. ActiveHome (ACPI-compliant) ), no temgo claro si hay que instalar algun driver... si es asi de donde saco el driver para Raspberry???

    Gracias y saludos
    Victor

    ResponderEliminar
    Respuestas
    1. tienes que tener instalado y en funcionamiento el mochad http://rsppi.blogspot.com.es/2012/06/domotica-en-raspberrypi-parte-1.html

      Eliminar
    2. Si tengo hecha la parte 1, de hecho me funciona bien... pero al hacer la parte 2 he visto que no tengo el /dev/cm15a0, creo que esto solo es cuando instala el driver para el cm15 verdad??? lo que no encuentro es el driver para raspberry.

      Eliminar
    3. es que no hay driver, el /dev/cm15a0 lo genera el mochad cuando esta en funcionamiento
      , lo tienes en marcha?

      Eliminar
    4. Si... lo tengo si.... es raro pero no me lo genera....

      Eliminar
    5. lo estoy viendo de nuevo y es verdad que no existe, lo crea el propio perl cuando va a usarlo ¿no te funciona?

      Eliminar
  4. Hola buenas tardes, me ocurre lo mismo que a anónimo me da el siguiente error.

    Cannot open device No existe el fichero o el directorio at ./domo.pl line 100.

    Supongo que es porque no encuentra /dev/cm15a0, como podría solucionarlo. el mochad esta en marcha y si uso el script del anterior post funciona a la perfección. También desde el Hangouts funciona sin ningún problema.

    Espero vuestra respuesta.
    Gracias.

    ResponderEliminar
    Respuestas
    1. la unica diferencia entre el script anterior o desde Hangout y este, es que este se ejecuta con el usuario www-data en lugar de root ¿has puesto la línea correctamente en el sudoers?

      Eliminar
  5. Gracias por contestar.

    La linea la tengo puesta tanto debajo de #User privilege specification y debajo de #includedir /etc/sudoers.d. He probado a poner el script del anterior post con la orden de encender y apagar (he creado una para cada cosa) y tampoco funciona. Me he dado cuenta que el html es algo diferente, por ejemplo no tengo ningún div y los cuadros para hacer clic no se llaman area shape sino area alt. He usado la misma pagina que mencionas por eso me parece un poco raro.

    Muchas gracias por ayudar.

    ResponderEliminar
  6. Hola, buenas tardes. He conseguido poder encender y apagar la luz gracias al script de la app de android. Y me queda una pregunta. Al hacer clic va al enlace y funciona correcto, pero me gustaria que se quedara en la imagen para no tener que dar atras cada vez. Hay alguna forma de hacerlo???.

    Espero vuestra respuesta.

    ResponderEliminar
    Respuestas
    1. Hola, de esa parte se encarga la linea:
      header("Location: http://192.168.1.2/index.html");
      asegúrate de que la URL apunta al html map de tu casa ;)

      Eliminar