viernes, 4 de noviembre de 2016

OpenHAB en RPi - Instalar OpenHAB


    En pasos anteriores de este blog hemos instalado el sistema operativo de la Raspberry PI 3 en un disco externo y le hemos asignado una IP fija. Estos pasos serán los mismos si quieres usar una Raspberry Pi como servidor de cualquier tipo.
    Ahora es el momento de instalar el software OpenHAB y realizar la personalización para que sea nuestro servidor de domótica.
    Además de OpenHAB, estas instrucciones instalan el servidor Mosquitto. Se trata de un servidor de mensajes para que los dispositivos basados en Arduino (y otros) se puedan conectar con el servidor OpenHAB y recibir instrucciones y enviar información.
    Las intrucciones que indico a continuación han sido adaptadas y traducidas de http://www.instructables.com/id/Install-OpenHAB-on-Raspberry-Pi/.
    Para esta instalación es necesario que la Raspberry Pi esté conectada a Internet para descargarse todos los paquetes.
    1. En primer lugar hay que conectarse por terminal a la Raspberry Pi. Puedes hacerlo por la consola del dispositivo usando un televisor, un teclado y un ratón o bien en remoto desde tu pc o Mac usando un cliente de SSH.
    Desde un Mac basta con abrir una ventana de terminal y ejecutar:
    ssh pi@192.168.1.3
    Sustituyendo la IP por la que hayas asignado a tu Raspberry Pi.
    1. Una vez conectado conviene comprobar que todos los paquetes que forman el sistema operativo están actualizados (como la habrás instalado hace poco siguiendo los pasos anteriores, debería ser así:
    sudo apt-get update
    sudo apt-get upgrade
    1. A continuación hay que comprobar si están instalado Java y Eclipse. Para ello ejecuta:
    which java
    1. Si no hay ninguna respuesta significa que no está instalado y tienes que hacerlo con el comando:
    sudo apt-get install oracle-java8-jdk -y
    1. Si en cambio aparece:
    /usr/bin/java
    Significa que ya está instalado y no tienes que ejecutar el comando anterior.
    1. A continuación hacemos lo mismo con:
    which eclipse
    1. Y si no hay respuesta se instala con:
    sudo apt-get install eclipse -y
    1. En cambio la línea
    /usr/bin/eclipse
    Indicará que ya estaba instalado.
    1. Seguidamente hay que instalar el servidor Mosquitto. Ejecuta los siguientes comandos (esperando a que termine cada uno antes de ejecutar el siguiente):
    sudo apt-key add mosquitto-repo.gpg.key
    rm mosquitto-repo.gpg.key
    cd /etc/apt/sources.list.d/
    sudo apt-get update
    sudo apt-get install mosquitto mosquitto-clients
    1. Ahora ya debería estar instalado y funcionando el servido Mosquitto. Una forma de comprobarlo es publicando un mensaje desde una ventana de Terminal y viendo en otra que aparece.
      1. En la ventana actual ejecuta:
    mosquitto_sub -d -t hola/mundo
    1. Ahora en abre otra ventana (o haz otro ssh sin cerrar el actual) y ejecuta:
    mosquitto_pub -d -t hola/mundo -m "Aqui estamos"
    1. En la primera ventana debe aparecer:
    Client mosqsub/10529-raspberry received PUBLISH (d0, q0, r0, m0, 'hola/mundo', ... (12 bytes))
    Aqui estamos
    1. Si es correcto, pulsa Control-C para terminar el programa de escucha y seguir con la instalación.
    2. El siguiente paso es la creación de los directorios que necesita OpenHAB para funcionar. Ejecuta:
    sudo mkdir /opt/openhab
    sudo chmod -R ugo+rw /opt/openhab
    1. Abre un navegador en tu ordenador y conectate a http://www.openhab.org
    2. Pulsa el enlace Downloads en la parte superior.
    3. Copia el enlace asociado al botón de descarga de Runtime Core (en Mac con Control-clic, en Windows con el botón derecho del ratón sobre el enlace)
    4. En la ventana de Terminal de Raspberry PI escribe
    cd /opt/openhab
    sudo wget 
    Y a continuación pega el enlace que has copiado. Te tiene que quedar algo similar a lo siguiente:
    Pulsa Intro y espera a que se termine de descargar el archivo.
    Haz
    ls
    Aparecerá el nombre del archivo que has descargado.  Copialo y escribe
    sudo unzip 
    Seguido del nombre del archivo:
    sudo unzip distribution-1.8.3-runtime.zip
    A continuación escribe
    rm distribution-1.8.3-runtime.zip
    El nombre del archivo tiene que ser el mismo de antes.
    Y contesta Y cuando te pregunte si quieres borrarlo.
    1. Repite los paso 11 y 12 con ek enlace Addons  de la página de descargas de OpenHAB. Es decir, con la versión 1.8.3 de OpenHAB pero ejecutando previamente el comando "cd /opt/openhab/addons":
    sudo unzip distribution-1.8.3-addons.zip
    sudo rm distribution-1.8.3-addons.zip
    1. Repite los pasos 11 y 12 con el enlace Demo Setup de la página de descargas de OpenHAB pero cambiando previamente al directorio /opt/openhab:
    sudo unzip distribution-1.8.3-demo.zip
    En este punto es posible que te pregunte varias veces si sustituye algún archivo existente. Contesta Y.
    rm distribution-1.8.3-demo.zip
    1. Una vez instalados los paquetes hay que cambiar los permisos al script de arranque de OpenHAB:
    sudo chmod +x start.sh
    1. Ya está instalado. Puedes arrancarlo a mano ejecutando:
    sudo /opt/openhab/start.sh
    1. El programa tarda un rato en arrancar (hasta 5 minutos). Al cabo de un rato  abre una ventana en tu navegador y escribe:
    Cambiando 192.168.1.3 por la IP que le diste a la Raspberry PI. Verás que te aparece la página inicial de tu OpenHAB. ¡Ya está instalado!
    1. Aunque funciona, ahora mismo tu instalación de OpenHAB tiene varias deficiencias, hay que arrancarla a mano (no se arranca automáticamente al encender la Raspberry Pi), no tiene usuario y contraseña y tiene instalados un gran número de añadidos que no son necesarios y que sólo dan errores.
    2. Todos estos puntos se corrigen en la siguiente entrada de este blog.

sábado, 29 de octubre de 2016

OpenHAB en RPi - IP Fija


Si has ejecutado los pasos de mi anterior entrada en el blog, tendrás tu Raspberry PI 3 con su disco externo (SSD o disco duro) de arranque funcionando.
Con independencia de que la conectes a la red por WiFi o Ethernet, la forma en que obtiene su dirección IP y los demás datos para conectarse a tu red local y a Internet es mediante DHCP. Este método es muy cómodo pero tiene el inconveniente de que la IP puede cambiar cada vez que arranques la máquina y en nuestro caso es necesario que este dispositivo tenga IP fija para que los dispositivos de Internet de las cosas que conectemos puedan conectarse a él.
A continuación explico como asignar una IP fija a la Raspberry Pi. Esta IP tiene que pertenener a la red a la que te vas a conectar y no tiene que ser la misma usada por ningún otro dispositivo. Además necesitarás saber la dirección IP del router de salida a Internet y la de un servidor DNS (puedes usar la de Google que es la 8.8.8.8). si no sabes como obtener estos datos, conviene que consultes con algún amigo con conocimientos de redes para que te ayude a encontrar los valores válidos.
Las instrucciones para la Raspberry PI  con sistemas operativos antiguos y nuevos son distintas. Para los antiguos ejecuta los pasos que indican en este tutorial: http://www.suntimebox.com/raspberry-pi-tutorial-course/week-3/day-5/ mientras que para la nueva versión (RaspBerry Pi 3) tienes que bajar en esa página hasta un comentario de BK del 20 de Marzo de 2016 a las 22:49. Estos pasos son los que indico aquí:
Conectate a tu Raspberry PI, abre una ventana de Terminal y ejecuta (nano es el nombre de un editor de textos):
sudo nano /etc/dhcpcd.conf
Ve al final del archivo con las flechas del teclado.
Si vas a usar conexión Ethernet añade la línea
interface eth0
Si vas a usar conexión WiFi añade la línea
interface wlan0
y a continuación añadir debajo de dicha línea las siguientes líneas (cambia estos valores por los correctos para tu red):
static ip_address=192.168.1.3
static routers=192.168.1.1
static domain_name_servers= 8.8.8.8 8.8.4.4
Address es la IP que has reservado para el dispositivo.
Routers es la IP del router de salida a Internet.
Los valores de domain_name_servers son los de los servidores de Google y puedes dejar estos (o usar otros que conozcas si lo prefieres).
Una vez que hayas añadido las líneas escribe Control-X (tecla Control y a la vez X. Te preguntará si guarda los cambios, contesta con Y a la siguiente pregunta del nombre del archivo contesta con Intro.
Finalmente hay que rebotar la Raspberry para que tome todos los cambios:
sudo reboot
Ten en cuenta que al arrancar lo hará con la nueva IP y por tanto tendrás que volver a conectarte con esta IP.

martes, 25 de octubre de 2016

OpenHAB en RPi. Paso 1, configurar la Raspberry Pi para usar un SSD


    Es perfectamente posible instalar OpenHAB en una Raspberry Pi, aunque conviene que sea una Raspberry Pi modelo 2 o 3, ya que el modelo 1 tiene un procesor bastante menos potente y puede darnos problemas a poco que la configuración de nuestra casa sea compleja.
    Pero si se busca en los foros, podeis comprobar que hay muchos usuarios que han instalado OpenHAB en una Raspberry PI, asi que me compré el modelo 3, una MicroSD de 64 GB y lo instalé.
    Estaba a punto de cambiar mi instalación actual (que se basa en un Mac Mini) a la Raspberry Pi cuando investigando en los foros descubrí que las tarjetas de memoria tienen un problema de desgaste: Si se escribe muchas veces sobre ellas, se estropean. Los sistemas operativos intentan mitigar este problema utilizando todo el espacio disponible de la tarjeta para distribuir las escrituras, por tanto con una tarjeta de 64 GB no debería haber muchos problemas.
    Pero aun así no me quedé tranquilo y decidí utilizar una funcionalidad nueva que está disponible de forma beta para la Raspberry Pi 3 (no para la 2 ni para la original, aunque el enlace que hay en el paso 1 mas adelante da una pista de como puede hacerse) y que consiste en un nuevo firmware que permite arrancar desde un disco USB.
    Así que me compre un disco USB de 120 GB de oferta (Toshiba OCZ TR150), lo instalé en una caja SATA a USB 3.0 de Seagate que tenía de una operación de "hacking" anterior (eso es otra historia) y me pusé a instalar todo. Desde el sistema operativo a OpenHAB sobre este disco duro.
    En esta entrada explico como configurar e instalar una Raspberry Pi para que use un disco SSD en lugar de una memoria MicroSD.
    A continuación teneis detallados los pasos que seguí, por si quereis emularlos, junto con el enlace a la web original donde encontré la información por si quereis ampliar los conocimientos y porque "al cesar lo que es del cesar".

    Paso 1: Configurar la Raspberry PI para que arranque de un disco USB
    Nota: Se supone que dispones de un disco USB externo conectable a tu Raspberry PI. Aquí no voy a explicar como se instala un disco SSDen una caja USB como hice yo, pero no es ciencia espacial.
    Nota2: Si no vas a utilizar esta opción y quieres seguir usando la tarjeta SD, salta al siguiente paso.
    Nota 3: Esta parte está extraida del blog de Raspberry Pi: https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/msd.md
    1. Coge una tarjeta MicroSD con capacidad suficiente para instalar Raspbian (el sistema operativo de Raspberry). En principio 4 GB son suficientes.

    1. Conectala a tu ordenador con el adaptador correspondiente.
    2. Inicializa la tarjeta con el formato FAT32 usando la utilidad correspondiente de tu sistema operativo
    3. De la página https://www.raspberrypi.org/downloads/raspbian/ descargate Raspbian Jessie With Pixel (no te descarges la versión Lite, porque implica más trabajo).
    4. En mi caso me descargué la versión 2016-09-23-raspbian-jessie
    5. Instala el software en la tarjeta MicroSD.
      1. En Windows hay que instalarlo con Win32DiskImager. El enlace para descargarlo y las instrucciones están en: https://www.raspberrypi.org/documentation/installation/installing-images/windows.md
      2. Para Linux las instrucciones están en https://www.raspberrypi.org/documentation/installation/installing-images/linux.md
      3. Para Mac (https://www.raspberrypi.org/documentation/installation/installing-images/mac.md):
        1. descomprime el archivo 2016-09-23-raspbian-jessie.zip (o la versión que has descargado). En Mac con un doble clic lo hará, en Linux gunzip 2016-09-23-raspbian-jessie.zip
        2. Antes de insertar la tarjeta en el ordenador (yo usé un adaptador MicroSD a USB) ejecuta el comando diskutil list | grep dev
        3. Te aparecerá una lista mas o menos larga con todos los discos que tiene montados el ordenador en ese momento:
    $ diskutil list | grep dev
    /dev/disk0
    /dev/disk1
    /dev/disk2
    /dev/disk3
    /dev/disk4
    /dev/disk5
    1. Conecta la tarjeta al ordenador con el adaptador USB (si la tarjeta es nueva, es posible que te aparezca un mensaje diciendo que si quieres inicializarla. Pulsa Ignorar) y vuelve a ejecutar el comando diskutil list | grep dev:
    $ diskutil list | grep dev
    /dev/disk0
    /dev/disk1
    /dev/disk2
    /dev/disk3
    /dev/disk4
    /dev/disk5
    /dev/disk6
    1. Observa que ahora hay un disco adicional, /dev/disk6. Esta es la tarjeta que vamos a usar.
    2. Ejecuta sudo umount /dev/disk6s* sustituyendo disk6 por el nombre que hemos averiguado en el paso anterior.
    3. Ahora escribe en el terminal SIN pulsar Intro al final "sudo dd bs=1m if="
    4. En el Finder arrastra el archivo con la imagen descomprimida en el paso c.i. encima de la ventana del Terminal, verás que después de if= se rellena automaticamente el directorio y nombre del archivo: sudo dd bs=1m if=/Volumes/A/Users/fernando/2016-09-23-raspbian-jessie.img 
    5. No pulses Intro todavia.  Detrás de la línea anterior añade: of=/dev/rdisk6 Fijate en dos detalles: Primero tienes que sustituir el 6 por el número del paso v. Segundo que en lugar de disk hay que escribir rdisk.
    6. La línea te quedará similar a esta sudo dd bs=1m if=/Volumes/A/Users/fernando/2016-09-23-raspbian-jessie.img of=/dev/rdisk6
    7. Ahora ya puedes pulsar Intro. El terminal te pedirá tu contraseña y cuando la escribas y pulses Intro, empezará a escribir la imagen de disco en la tarjeta. Este proceso tarda tiempo, así que aprovecha y tomate un buen capuchino.
    8. Una vez terminada la copia, vuelve a ejecutar:sudo umount /dev/disk6s*
    1. Extrae la tarjeta MicroSD e insertala en tu Raspberry Pi 3.
    2. Conecta la Raspberry Pi a tu televisor o monitor, enchufale tu teclado y ratón y enciendela conectando el cargador USB.
    3. Una vez que haya arrancado el sistema operativo, tienes que conectarla a Internet. La forma mas sencilla es con un cable Ethernet entre tu router de fibra o ADSL y el puerto Ethernet de la Raspberry Pi. Si no tienes Ethernet y/o quieres usar la WiFi, en la parte derecha del menú superior verás un icono con dos flechas, una para arriba y otra para abajo, pulsalo y en la lista de redes WiFi que aparecen verás el nombre de la tuya, elígela, introduce la contraseña correspondiente y te conectaras a la WiFi y a Internet.
    4. El teclado está en inglés. Si quieres cambiarlo a Español, en el menú superior izquierdo, despliega el icono Raspberry y en la opción Preferences elige Mouse and Keyboard Settings
    5. En el diálogo que aparece pulsa la pestaña Keyboard y a continuación el botón Keyboard Layout
    6. En el nuevo diálogo que aparece elige Country Spain y Variant Spain. Pulsa OK en los dos diálogos y ya tienes el teclado con la disposición de Españo.
    7. Una vez conectado a Internet, abre una ventana de Terminal (menú superior, icono Raspberry, despliega y en Accesories elige Terminal)
    8. Escribe sudo apt-get update; sudo apt-get install rpi-update y pulsa Intro.
    9. Cuando acabe ejecuta sudo BRANCH=next rpi-update
    10. Ahora hay que activar el arranque desde USB en la Raspberry Pi (si, todo lo que hemos hecho hasta ahora era solo para activar esto): echo program_usb_boot_mode=1 | sudo tee -a /boot/config.txt
    11. Reinicia la Raspberry Pi con sudo reboot
    12. Para comprobar que se ha programado correctamente, después de arrancar vuelve a abrir el Terminal y ejecuta: vcgencmd otp_dump | grep 17:
    1. La salida tiene que ser 17:3020000a
    2. Nuestra Raspberry Pi está finalmente preparada para usar el disco SSD.
    3. Conecta el disco USB a cualquier puerto USB de la Raspberry Pi. Tal como indica en la página indicada al principio, la tarjeta MicroSD será /dev/mmcblk0 y el primer disco USB que conectemos será /dev/sda
    4. Ejecuta sudo parted /dev/sda
    Aparecerá el siguiente mensaje:
    GNU Parted 3.2
    Using /dev/sda
    Welcome to GNU Parted! Type 'help' to view a list of commands.
    (parted)
    1. Escribe mktable msdos
    2. Si el disco ya ha sido usado o tiene una estructura de archivos creada, te avisará que lo va a borrar y que se perderán todos los datos grabados en él. Te pregunta si quieres continuar y contesta que Yes
    1. A continuación hay que crear dos particiones en el disco USB. Una primera partición de 100 Megabytes para el arranque y el resto (casi 120 GB) para el sistema operativo en si.
    2. El mensaje (parted) sigue apareciendo, escribe: mkpart primary fat32 0% 100M esto le dice que cree una partición desde el principio del disco y que ocupe 100MB.
    3. Vuelve a aparecer (parted) y ahora escribe mkpart primary ext4 100M 100% que dice que se cree una segunda partición desde los 100 MB hasta el final del disco.
    4. En el siguiente (parted) escribe print para ver que particiones se han creado. En mi caso:
    Model: Seagate Expansion (scsi)
    Disk /dev/sda: 120GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    Disk Flags: 

    Number  Start   End     Size    Type     File system  Flags
     1      1049kB  99.6MB  98.6MB  primary  fat32        lba
     2      99.6MB  120GB   120GB   primary  ext4         lba
    1. Seguidamente escribe quit para salir del programa parted.
    2. Ahora creamos los sistemas en las particiones que acabamos de crear:
    sudo mkfs.vfat -n BOOT -F 32 /dev/sda1
    sudo mkfs.ext4 /dev/sda2
    1. En lugar de volver a instalar el sistema operativo como hicimos con la tarjeta MicroSD, la siguiente secuencia de operaciones copia todo el sistema desde la MicroSD al disco USB. El úlitmo paso llevará bastante tiempo, momento para un segundo café. Nota: si vas a copiar los comandos hazlo hasta la penúltima línea, espera a que termine de ejecutarse y luego ejecuta la última.
    sudo mkdir /mnt/target
    sudo mount /dev/sda2 /mnt/target/
    sudo mkdir /mnt/target/boot
    sudo mount /dev/sda1 /mnt/target/boot/
    sudo apt-get update; sudo apt-get install rsync
    sudo rsync -ax --progress / /boot /mnt/target
    1. La clave SSH, la que utiliza el sistema cuando te conectas en remoto con SSH hay que volver a regenerarla en el nuevo disco con los siguientes comandos (puedes copiar y pegar todos los comandos en una ventana ssh de tu Raspberry Pi):
    cd /mnt/target
    sudo mount --bind /dev dev
    sudo mount --bind /sys sys
    sudo mount --bind /proc proc
    sudo chroot /mnt/target
    rm /etc/ssh/ssh_host*
    dpkg-reconfigure openssh-server
    exit
    sudo umount dev
    sudo umount sys
    sudo umount proc
    1. Los últimos pasos es modificar los parámetros de arranque para que se arranque del disco USB:
    sudo sed -i "s,root=/dev/mmcblk0p2,root=/dev/sda2," /mnt/target/boot/cmdline.txt
    sudo sed -i "s,/dev/mmcblk0p,/dev/sda," /mnt/target/etc/fstab
    1. Para terminar, desmonta todos los discos y apaga la Raspberry Pi:
    cd ~
    sudo umount /mnt/target/boot
    sudo umount /mnt/target
    sudo poweroff
    1. Hecho esto, desconecta la  Raspberry Pi de la alimentación, extrae la tarjeta MicroSD y vuelve a conectarla. Si todo ha ido bien, arrancará desde el disco USB.
    2. Queda un punto pendiente. Si ahora haces un apt-get para actualizar el software, volverá a modificar los archivos anteriores e intentará arrancar de la MicroSD. Para solucionarlo ejecuta los siguientes comandos:
    sudo rm /boot/.firmware_revision
    sudo apt-get update && sudo apt-get -y dist-upgrade && sudo BRANCH=next rpi-update
    1. Hecho esto, el sistema seguirá arrancando desde el disco USB las siguientes ocasiones.
    Siguiente paso: instalar OpenHAB en el sistema.

miércoles, 28 de septiembre de 2016

Automatizar mi casa (prólogo)

Después de pensar mucho y estar investigando el mercado, he decidido empezar a automatizar mi casa para que sea más eficiente y cómoda, lo que se llama Home Automation en inglés o Domótica en castellano, pero no hay ninguna solución comercial que dé todo lo que pido, control de luces, calefacción, alarmas, programación horaria, estación meteorológica, etc. Y que además sea totalmente configurable.
Además tampoco quiero depender de servidores externos (que pueda usarlos es una cosa, que esté obligado a usarlos es distinto) para evitar que me pase lo que a los usuarios de Revolv, un sistema de automatización del hogar creado por Google y que ha decidido discontinuar con el pequeño inconveniente de que al estar basado en la nube, al discontinuarlo el aparato que se compraron los usuarios se ha convertido en un pisapapeles muy caro.
Así que me lié la manta a la cabeza y he decidido montármelo todo por mí mismo, DIY, junto con algunas Soluciones Open Source.
En este serie de entregas contaré como lo he hecho, proporcionando todos los detalles necesarios por si alguien quiere copiarlo o (mejor) mejorarlo y adaptarlo. Cualquier sugerencia será también bienvenida.

Herramientas

Para el controlador y después de algunas investigaciones (no las suficientes, pero muchas), me he decidido por implementar OpenHAB (http://www.openhab.org/). Es muy versátil permite hacer todo lo que yo quiero, y eso que hay cosas realmente difíciles de implementar en mi proyecto, pero a cambio es muy complejo de configurar y si hubiera un libro de OpenHAB, uno bueno, me lo compraría.
OpenHAB soporta un gran número de módulos de diversos fabricantes, incluyendo las bombillas Vue de Philips, diversos equipos multimedia y televisores con conexión WiFi, sistemas de domótica de Netatmo, etc. Sin embargo dado que la mayoría de mis módulos son desarrollados por mí mismo, OpenHAB no los soporta directamente,  pero para estos casos  la recomendación es usar MQTT.
MQTT es un Broker de mensajes.  Definido de forma sencilla es un servidor al que se publican mensajes asociados a un tópico. Por ejemplo podemos publicar en el tópico "Entrada" el mensaje "ON". Además los tópicos pueden ser jerárquicos. Puede haber  una jerarquía "Bombillas" debajo de la cual cuelga "Entrada". Entonces publicaríamos "ON" al tópico "Bombillas/Entrada” para indicar que queremos encender esa bombilla.
Aparte de elementos que publican también hay subscriptores. En el caso anterior, nuestra bombilla, con conexión WiFi, se suscribirá al tópico Bombillas/Entrada y en este caso el servidor la avisará cuando haya un mensaje ON u OFF y la bombilla actuará en consecuencia.
Inicialmente monte ambos servicios, OpenHAB y el servidor MQTT (mosquitto) en un MacMini que tengo de servidor multimedia en casa, pero he decidido migrarlos a su propio servidor basado en una Raspberry PI 3. Así que aquí incluiré las instrucciones para este último caso.

Sensores y actuadores

Todo el hardware muestra (por lo menos en el momento de escribir este artículo), la evolución de lo que estoy aprendiendo y no esperes encontrar la mejor solución descrita paso a paso. Si volviera a empezar elegiría otras soluciones para muchas necesidades, pero aquí está lo que he implementado y está funcionado –eso es importante, que funciona– y espero que te sea de utilidad.
Parte de las soluciones están hechas basándose en Arduino con el módulo WiFi ESP8266, posteriormente descubrí como usar el ESP8266 de forma independiente y lo he usado para otros elementos del hogar.

Todos los módulos están configurados para poder funcionar de forma autónoma, si se cae el servidor OpenHAB y/o MQTT, los interruptores podrán seguir encendiendo y apagando las bombillas, la calefación funcionará, etc. pero perderé la posibilidad de control central desde el movil (u otra herramienta).

Además este sevidor central sirve para darle inteligencia a la casa. Por ejemplo tengo una luz en el porche de la entrada. En lugar de encenderlo y apagarlo a mano, se encenderá y apagará automáticamente basado en la liuz exterior. Para ello necesito una estación meteorológica (en realidad he montado dos) que me de el valor de luz y de paso de humedad y temperatura para el control de la calefación.

Esto es la introducción. En la siguiente entraga, como montar OpenHAB

domingo, 22 de mayo de 2016

Spanning tree, caminos unidireccionales y la importancia de la prioridad

El nivel 2, es decir el switching, es menospreciado por muchos ingenieros de red, incluso por mi, que lo consideran poco interesante. 

Sin embargo para bien o para mal es imprescindible para el funcionamiento de todas las redes y los problemas que podemos tener a nivel 2, lejos de ser triviales y aburridos, pueden darnos horas y horas de entretenida depuración. 

Hoy voy a contaros un incidente que tuve recientemente y que enseña que no podemos ignorar o despreciar ningún (y ningún es ningún) detalle de configuración a nivel dos.

El escenario

De forma resumida el escenario que teniamos era el siguiente:
Con la sede central a la izquierda y una delegación a la derecha

El tráfico llegaba a Catalyst 4500 de la izquierda, dos VLAN funcionando en modo SVI, es decir un “switch” con un “router” asociado, era transmitido por un radio enlace que se comportaba como un bridge y transmitido a una tarjeta switch de cuatro puertos de un Cisco 2911.

Dicho tráfico constaba de dos VLAN:

- Una de datos de usuario.
- La segunda de configuración del radioenlace remoto.

Esta segunda es el meollo del problema, porque es posible configurar el ancho de banda de transmisión y de recepción del radioenlace mediante comandos SNMP que enviamos a la antena correspondiente.

A la que envía no hay problema, se le envía el comando desde la sede central a la antena y se reconfigura.

Sin embargo reconfigurar la transmisión en sentido contrario tiene un poco más de “truco”:

En primer lugar hay que entender que lo primero que hace la reconfiguración del ancho de banda, es desconfigurar el camino de vuelta para configurar el nuevo. Por tanto durante la reconfiguración (que son varios comandos SNMP), no hay trafico de vuelta.

La antena tiene un puerto específico de gestión y no “escucha” lo que recibe por radio. Lo que se hace es que el 2911 recibe la VLAN de gestión y por una conexión directa al puerto de gestión del radioenlace, le envía los datos.

Por tanto, y aunque no haya camino de retorno, la reconfiguración es como sigue:
- Desde el sistema de gestión (no dibujado) los paquetes SNMP llegan al router del Catalyst 4500
- Este los envía por la VLAN correspondiente al radio enlace
- Llegan al switch del CPE que los pasa al router del CPE
- El router del CPE envía (no dibujado) el paquete SNMP al puerto de gestión del radio enlace

Algún avispado lector se habrá dado cuenta de un pequeño detalle, Antes de que se pueda enviar un paquete al CPE remoto, se tiene que ejecutar una petición ARP para que el Catalyst 4500 aprenda la MAC address del CPE y poder enviarle paquetes, y si no hay camino bidireccional, el CPE remoto no podrá contestar a dicha petición ARP con su MAC address.

para evitar este problema se ha configurado estáticamente la MAC del CPE en el Catalyst 4500 con la instrucción:

arp 10.10.20.1 0002.3333.ffff ARPA

Siendo 10.10.20.1 la IP del CPE y 0002.3333.ffff la MAC address asociada. Con esto se evita que se tenga que ejecutar la resolución ARP y los paquetes SNMP pueden enviarse incluso con comunicación unidireccional.

Hasta aquí, muy bien.

El problema

Se descubrió que a menudo durante la reconfiguración, el radioenlace remoto se quedaba desactivado como si no hubiera recibido todos los comandos, a pesar de que se enviaban desde el sistema de gestión.
Para complicar más las cosas había varias sedes remotas y el problema solo sucedía con algunas de ellas continuamente, a pesar de que todas tenían la misma configuración y equipamiento (incluso la misma versión de IOS).

Diagnostico

Como hemos dicho el Catalyst 4500 funciona en modo SVI, lo mismo que la interfaz del 2911 conectada al radioenlace. Esto hace que lógicamente en nuestro esquema tengamos dos switches y un bridge:
Normalmente en un entorno de switching de este tipo la situación del nodo raíz del STP (Spanning Tree Protocol) no sería importante. El STP se configura eligiendo como root cualquiera de los switches y todo funciona.

Si en ese entorno se produce un corte en el camino (radioenlace), se crean dos VLAN separadas que operan independientemente y la comunicación entre los dos segmentos no es posible:

En este caso cada segmento tiene su propio root. En un lado el Catalyst 4500 y en el otro el switch del CPE.

Cuando vuelve a recuperarse el enlace, se empiezan a enviar BPDUs bidirecionalmente y se produce un nuevo proceso de selección de root.

Esta elección retrasa unos segundos (o decimas) el establecimiento del path y la posibilidad de envío de paquetes.

Sin embargo en nuestro caso la situación es mas compleja.

Cuando sólo se quiere configurar el camino de vuelta,  se envían los paquetes a la sede remota para que el radioenlace cambio su ancho de banda, y como hemos dicho, lo primero que hace es deshabilitar el camino de vuelta.



Las BPDU dejan de fluir desde el CPE al 4500 y el 4500 considera el STP interrumpido. Si el bridge root es el Catalyst 4500 (por prioridad o MAC address mas bajas), no hay problema, sigue enviando los paquetes que reciba (SNMP) y el CPE los recibe y enruta al radioenlace.

Esto es lo que permite configurar el extremo remoto del radio enlace incluso con un camino unidireccional.

Sin embargo, si el bridge root es el CPE, al dejar de recibir los BPDU el 4500, bloquea el puerto, espera que expiren los timers correspondientes y se produce una nueva elección de root. Durante ese tiempo el camino está bloqueado y hasta que el 4500 no decide que él es el nuevo bridge root, no permite el envío de paquetes, provocando la pérdida de paquetes SNMP de configuración.

Sin embargo cuando el camino de retorno se levanta, el Catalyst 4500 y el switch del CPE remoto empiezan a intercambiar BPDU y se procede a elegir un nuevo root del STP.

Por tanto si la prioridad se deja por defecto (¿porque no? podemos preguntarnos, a priori no había razón para que uno u otro fuera el raíz, o el enlace funciona o no funciona), interviene la MAC address y si la MAC address del 2911 es inferior a la del 4500, al  cortarse el circuito este último considera que tiene que dejar de ser root y mientras recalcula el STP deja de enviar tráfico por esa VLAN.

Si, como pasaba en nuestro caso, son necesarios mas paquetes SNMP para completar la configuración, estos pueden intentar enviarse durante esta conmutación, no llegar y el radioenlace dejar de funcionar.

Solución

Por tanto para que funcione siempre el radioenlace, además de configurar estáticamente la MAC address del CPE remoto en el Catalyst 4500, hay que configurar a éste como root en dicha VLAN con la instrucción:
spanning-tree vlan 100 root primary
Esto evitará que el CPE se convierta el root y se produzca un bloqueo temporal de la comunicación.

Añadidos

Para aquellos interesados en saber como descubrí el problema, la primera pista me la dio la aparición en los logs del Catalyst 4500 de los siguientes mensajes:

May 18 14:30:17 UTC: %SPANTREE-5-TOPOTRAP: Topology Change Trap for vlan 100
May 18 14:30:17 UTC: %SPANTREE-5-ROOTCHANGE: Root Changed for vlan 100: New Root Port is GigabitEthernet4/3. New Root Mac Address is 0002.3333.ffff

Luego tuve una divertida sesión de debug en STP, pero sólo hizo confirmar mis sospechas.