Contenido


Lleve el IoT a su casa: conecte su automóvil hacia su casa

Utilice IBM Watson IoT Platform y un Raspberry Pi, un dispositivo Bluetooth y una regleta de enchufes programable para encender sus luces y electrodomésticos a medida que su automóvil se aproxima a la casa

Comments

Los automóviles conectados y las casas inteligentes son los principales temas actuales en el campo del IoT. Si lo observa más de cerca, descubrirá que los automóviles conectados y las casas inteligentes parecen estar en silos. Sí, una casa residencial inteligente es capaz de encender las luces y electrodomésticos con su teléfono móvil. Pero ¿por qué no puede hacer lo mismo el automóvil a medida que se está aproximando a la casa inteligente?

En este tutorial, aprenderá cómo utilizar IBM Bluemix y Node-RED para conectar un automóvil a una casa inteligente, habilitando que el automóvil active automáticamente los dispositivos domésticos, como encender las luces y ajustar el aire acondicionado.

Utilizaremos un Raspberry Pi para sentir la fuerza de la señal de un dispositivo Bluetooth de la casa inteligente y enviaremos esa información a Watson IoT Platform. Después, basándonos en la fuerza de la señal, encenderemos un electrodoméstico con ese dispositivo Bluetooth. También, utilizaremos el rastreamiento basado en GPS del automóvil, para crear una geovalla alrededor de la casa inteligente, esencialmente para ser capaz de conectar el automóvil a la casa.

Qué necesitará para construir esta aplicación IoT

Este tutorial práctico está basado en una Prueba de Concepto (PoC) que realicé con poca antelación con equipamientos que encontré en casa en el momento en el que hice la PoC. Para ese propósito en particular, puede utilizar los mismos dispositivos, o puede sustituirlos por lo que necesite.

Necesita los siguientes dispositivos, cuentas o habilidades para construir esta aplicación de IoT como yo la construí:

  • Un sistema Linux con un dispositivo Bluetooth, como Raspberry Pi con una llave USB Bluetooth. Aunque funcionará con cualquier dispositivo Linux que esté configurado con un C-Compiler, realmente nadie quiere ejecutar una computadora durante 24 horas los 7 días de la semana como un dispositivo gateway.
  • Desde un PC se puede encender una regleta. Yo utilicé una Gembird Silver Shield (regleta programable), pero hay otras marcas que a usted le pueden venir mejor.
  • Estar familiarizado con el lenguaje de programación C y el desarrollo con C en un sistema Linux (como Fedora, que es un sistema operativo de código abierto basado en Linux).
  • Una cuenta de IBM Bluemix® . (Puede solicitar una prueba gratuita aquí. O, ¿sabía que developerWorks Premium le da una suscripción por 12 meses para IBM Bluemix y 240 USD en créditos para la nube de Bluemix?)
  • Estar familiarizado con Bluemix. Necesita saber cómo explorar el catálogo y crear una instancia de uno de los servicios de Bluemix.
  • Estar familiarizado con MQTT, especialmente con la biblioteca Eclipse Mosquitto, que se un bróker de mensajería de código abierto que implementa el protocolo MQTT y que puede encontrar en todas las principales distribuciones de Linux. Utilice su herramienta de gestión de paquetes de plataformas de Linux para buscar Mosquitto e instale el paquete en su dispositivo.
  • Estar familiarizado con Node-RED. Necesita entender cómo utilizar nodos en Node-RED y cómo procesar un mensaje en Node-RED. Node-RED es un front end de JavaScript, así que también necesitará algo de experiencia con JavaScript. Es posible utilizar la documentación de cómo empezar del sitio web de Node-RED para obtener ayuda para lograr esa familiaridad.

Obtener el códigoEjecutar la aplicación

 

La arquitectura de nuestra aplicación IoT de muestra

Figura 1 representa la primera fase de la arquitectura de la aplicación IoT que recibe la fuerza de la señal del Bluetooth.

Figura 1. Diagrama de arquitectura de la aplicación y dispositivos IoT de muestra

En Figura 1, los números de los círculos le guían a través de los pasos para construir la aplicación IoT:

  1. En IBM Bluemix, usted crea una aplicación utilizando Internet of Things Platform Starter. La aplicación leerá los datos de sensor que recibe desde un dispositivo y enviará datos a un dispositivo. Para proteger a la aplicación de que la envíen datos dispositivos arbitrarios, cada dispositivo necesita autenticarse utilizando un token de API. De igual manera, para ser capaz de leer y procesar los datos que recibe del dispositivo, la aplicación necesita autenticarse mediante la utilización de un token de API.
  2. En un dispositivo Raspberry Pi, usted crea un cliente MQTT para leer la fuerza de la señal del Bluetooth y envía continuamente los valores a la plataforma IBM Watson IoT.
  3. Crea una aplicación Node-RED para procesar los datos y generar los comandos que va a enviar a la regleta programable para encender las luces y el aire acondicionado de la casa.

Después de implementar correctamente esta versión inicial de la aplicación IoT, aprenderá cómo extenderla para tener en cuenta las coordinadas GPS del automóvil. También desarrollará un panel de instrumentos para definir la geovalla para que funcione el control GPS y para establecer la sensibilidad del sensor de aproximación Bluetooth.

¡Pongámonos en marcha!

Crear su aplicación IoT y conectar su Raspberry Pi a Watson IoT Platform

Primero, conectemos nuestra Raspberry Pi a Watson IoT Platform.

Crear su aplicación IoT en Bluemix

  1. Inicie sesión en su cuenta de Bluemix.
  2. Para crear su aplicación utilice el texto reutilizable de Internet of Things Platform Starter. Para la aplicación puede escoger su propio nombre; en este tutorial yo utilizo dw-example-iot. La aplicación se iniciará, lo que puede tardar algún tiempo.
  3. Haga clic en el enlace de visión general que está en el panel de navegación de la izquierda y espere a que se despliegue del servicio.
  4. Haga clic en AÑADIR UN SERVICIO O API.
  5. Encuentre el servicio Internet of Things Platform y haga clic en CREAR.

Registre su Raspberry Pi con el servicio Internet of Things Platform e identifique los tokens de autenticación y autorización

Para enviar datos a Watson IoT Platform, necesita registrar sus dispositivos en el servicio de Internet of Things Platform. En este tutorial, utilizo la Raspberry Pi como dispositivo gateway. El token de autenticación que se genera cuando registra su dispositivo permite que el dispositivo envíe los datos a Watson IoT Platform.

Para identificar un dispositivo como único, necesita un ID del cliente. El ID del cliente se crea con un formato predefinido, en el que typeid es una cadena de caracteres que identifica el propósito de los dispositivos y "device-id" es el identificador único de su dispositivo:
d:<organization>:<typeid>:<device-id>

Envíe el siguiente comando a su dispositivo Raspberry Pi para identificar la dirección MAC única del mismo, que puede utilizar como el device-id único:
ip add show|grep -A1 '^[0-9]:'

En la salida del comando, busque una interfaz llamada 'eth0', 'em1', o similar a 'enp1s0'. Los nombres varían entre las distribuciones de Linux, pero la línea después de las interfaces muestra su dirección MAC como 'link/ether':

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
--
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 12597 qdisc pfifo_fast state UP….
link/ether b8:72:be:f2:7a:a8 brd ff:ff:ff:ff:ff:ff

Para registrar su dispositivo, realice estos pasos:

  1. En el panel de información de su aplicación Bluemix, haga clic en el servicio Internet of Things Platform.
  2. Abajo, en la columna de izquierda, haga clic en Lanzar panel de información. En su navegador se abrirá una nueva ventana o pestaña. El ID de su organización se muestra en la parte superior del panel de información.
  3. En la sección Dispositivos debajo de ID de la Organización, haga clic en Añadir Dispositivo.
  4. Especifique proximidad como tipo de dispositivo (typeid), y especifique la dirección MAC de su dispositivo de Ethernet, sin los símbolos de dos puntos, como ID de su dispositivo (device-id).
  5. Haga clic en Continuar.
  6. Revise cuidadosamente la siguiente página, y tome nota de las credenciales del dispositivo, más específicamente del Token de Autentificación de su dispositivo.

Pruebe su conectividad

Ahora que ya hemos registrado nuestro dispositivo con Watson IoT Platform, se puede utilizar el token de autenticación para enviar un mensaje de prueba desde el Raspberry Pi. Utilicemos la biblioteca de Mosquitto MQTT. Por ejemplo, inicie sesión en su Raspberry Pi y emita el siguiente comando de Mosquitto, suministrando los valores de su propia organización y device-id:

mosquitto_pub -h e62whi.messaging.internetofthings.ibmcloud.com \
-i d:e62whi:proximity:b872bef27aa8 \
-u use-token-auth -P '<aquí van las credenciales de su dispositivo>' \
-t /iot/x -m '{"d":"hola iot"}'

En el panel de información de Watson IoT Platform, verá el mensaje "hola iot" en la información del sensor de su dispositivo:

Mientras estamos en el panel de información de Watson IoT Platform, asegurémonos de que nuestra aplicación de Node-RED tiene autorización para consumir los datos del dispositivo que se envían a nuestra aplicación IoT. En vez de un token de autenticación, necesitamos un token de autorización de la API. Para autorizar que una aplicación consuma los datos de esta aplicación, complete estos pasos:

  1. En el panel de información de Watson IoT Platform, haga clic en Acceso y luego Claves de APIs.
  2. Haga clic en Generar clave de la API.
  3. Revise cuidadosamente la siguiente página, y tome nota de las credenciales de la API, más específicamente del Token de Autentificación.

Escriba un cliente MQTT para leer la fuerza de la señal del Bluetooth en su Raspberry Pi

El cliente MQTT es un programa en C que lee la fuerza de la señal Bluetooth y envía el valor a la aplicación IoT que está en Bluemix. De igual manera, el cliente recibe los comandos desde la aplicación IoT y llama a un script para que realice el comando.

Determinar la dirección MAC de su dispositivo Bluetooth

El cliente del dispositivo tiene que conectarse a un dispositivo Bluetooth mediante la utilización de la dirección MAC del dispositivo. Puede determinar la dirección MAC de su dispositivo Bluetooth emitiendo los siguientes comandos en su dispositivo (un Raspberry Pi en mi caso), que deberían brindar similares resultados o salidas:

# bluetoothctl
[NEW] Controller 00:15:83:07:CC:97 traumcloud.enet [default]

[Bluetooth]# power on
Changing power on succeeded
[CHG] Controller 00:15:83:07:CC:97 Powered: yes

[Bluetooth]# scan on
Discovery started
[CHG] Controller 00:15:83:07:CC:97 Discovering: yes
[NEW] Device 3C:77:E6:EF:57:F5 3C-77-E6-EF-57-F5
[NEW] Device 00:0A:3A:2B:C6:ED MSI FT200
[CHG] Device 00:0A:3A:2B:C6:ED RSSI: -79
[CHG] Device 00:0A:3A:2B:C6:ED RSSI: -88

[Bluetooth]# agent on
Agent registered

[Bluetooth]# pair 00:0A:3A:2B:C6:ED
Attempting to pair with 00:0A:3A:2B:C6:ED
Request PIN code
[agent] Enter PIN code: 1234
[DEL] Device 3C:77:E6:EF:57:F5 3C-77-E6-EF-57-F5
[CHG] Device 00:0A:3A:2B:C6:ED Connected: yes
[CHG] Device 00:0A:3A:2B:C6:ED UUIDs:
        00001108-0000-1000-8000-00805f9b34fb
        0000111e-0000-1000-8000-00805f9b34fb
[CHG] Device 00:0A:3A:2B:C6:ED Paired: yes
Pairing successful

[Bluetooth]#exit

En mi ejemplo, sé que estoy buscando unos auriculares MSI FT200, y veo que su dirección MAC es 00:0A:3A:2B:C6:ED. Anote la dirección MAC de su dispositivo.

Codificar el núcleo de MQTT

Después de haber iniciado la biblioteca de Mosquitto, el programa establece las llamadas de vuelta para los eventos en los que está interesado, y conecta con el servicio Internet of Things Platform de Bluemix. El código de inicio sigue esencialmente el código de ejemplo del sitio web de Mosquitto:

        mqtt = mosquitto_new(cfg.deviceid, 1, NULL);
        if(!mqtt){
                tprintf("No se puede iniciar la biblioteca MQTT\n");
                mosquitto_lib_cleanup();
                return 1;
        }
        mosquitto_connect_callback_set(mqtt, bt_connect_callback);
        mosquitto_disconnect_callback_set(mqtt, bt_disconnect_callback);

Después, usted añade los códigos de llamada de Mosquitto para los eventos de MQTT:

        mosquitto_log_callback_set(mqtt, bt_log_callback);
        mosquitto_message_callback_set(mqtt, bt_message_callback);
        mosquitto_subscribe_callback_set(mqtt, bt_subscribe_callback);
         dprintf("estableciendo ahora el nombre de usuario y la contraseña a %s/*************\n", cfg.username);
        sts=mosquitto_username_pw_set(mqtt, cfg.username, cfg.password);
        if(sts) {
                tprintf("Error al establecer el nombre de usuario/contraseña\n");
                return sts;
        }
        dprintf("now connection using host=%s port=%d\n", cfg.host, cfg.port);
        sts = mosquitto_connect_bind(mqtt, cfg.host, cfg.port, 60, NULL);
        if(sts) {
                tprintf("Error al conectar a %s:%d como %s\n", HOST, PORT, IDFMT);
                return sts;

Después, el programa se suscribe cuando la devolución de la llamada de la conexión indica que hay una conexión adecuada:

void bt_connect_callback(struct mosquitto *mqtt, void *obj, int result) {
         char buf[1024];
        dprintf("conn cb %d '%s'\n", result, mosquitto_connack_string(result));
        is_connected=(result==0?CONN_OK:CONN_ERR);
        if (is_connected==CONN_OK) {
                mosquitto_subscribe(mqtt, NULL, cfg.subscription, 0);
        }
        sprintf(buf, PAYLOAD, -100, -100); // simula una baliza muy lejana
        mosquitto_publish(mqtt, NULL, TOPIC, strlen(buf), buf, 0, false);
}

El programa principal se ejecuta en un bucle, que envía periódicamente la fuerza de la señal del Bluetooth.

while (is_connected != CONN_ERR) {
                if (is_connected == CONN_OK) publish_bt(mqtt);
                else dprintf("esperando a que la señal se levante\n", "");
                sleep(cfg.sleep);
        }

Llamar a un script externo

La biblioteca de Mosquitto se ocupa de recibir los comandos y llama a la función de devolución de llamada adecuada. En nuestro caso, llamamos a un script externo para que realice el trabajo real. Este script nos permite ser flexibles con los diferentes tipos de activadores para controlar los electrodomésticos.

void bt_message_callback(struct mosquitto *mqtt, void *udata, const struct mosquitto_message *message) {
        dprintf("msg cb topic='%s' payload='%s'\n", message->topic, message->payload);
/*
 * Un script de ejecución btclient.d/command.sh
 */
         int pid,sts;
        pid = fork();
        switch (pid) {
        case 0:         // secundario, ejecuta el script de shell
                setenv("TOPIC", message->topic, 1);
                setenv("PAYLOAD", message->payload, 1);
                sts=execl("btclient.d/mqtt-command.sh", "mqtt-command", (const char*)NULL);
                tprintf("algo salió mal con execl(), error='%s'\n", strerror(errno));
         break;
        case -1:        // error
                tprintf("algo salió mal con fork(), error='%s'\n", strerror(errno));
        break;
        default:        // principal
                wait(&sts);
        break;
        }
}

Al utilizar un script, el cliente MQTT se puede adaptar fácilmente al hardware o dispositivos inteligentes que utilice. Yo utilicé una regleta Gembird Silver Shield programable, que me deja controlar el encendido individual de cuatro regletas mediante la utilización de un USB con una utilidad de Linux llamada sispmctl (que está disponible un paquete en Fedora Linux).

#!/bin/bash
if [ "$TOPIC" == "iot-2/cmd/switch/fmt/text" ];then
        [ "$PAYLOAD" == "on" ] && arg="-o4"
        [ "$PAYLOAD" == "off" ] && arg="-f4"
        [ "$arg" != "" ] && sispmctl $arg
fi

Alternativamente, utilicé un transmisor-receptor de 433 MHz para activar las regletas inalámbricas mediante la utilización de la infraestructura pilight. La infraestructura pilight es una infraestructura para la automatización del hogar en Raspberry Pi. Puede investigar qué regleta y proyecto se ajustan a sus necesidades.

Modifique el archivo de configuración del cliente MQTT

Cuando se inicia el cliente MQTT lee un archivo de configuración, que tiene el mismo nombre del archivo ejecutable, pero con .cfg al final. Este archivo de configuración separado le permite ejecutar diferentes instancias simplemente utilizando un nombre diferente para el archivo ejecutable; por ejemplo, después de iniciar otherclient , el cliente MQTT leerá otherclient.cfg como su archivo de configuración.

El archivo de configuración define:

  • btmac: Utiliza la dirección MAC del dispositivo Bluetooth al que usted mide la fuerza de la señal (no el dispositivo integrado de su sistema Linux).
  • subscription: Utiliza el tema al que el cliente necesita suscribirse. En mi ejemplo, iot-2/cmd/switch/fmt/+.
  • host: El nombre del host de la instancia de su servicio de Internet of Things Platform. Utilice el mismo nombre que usó cuando envió el mensaje "hola iot".
  • password: La contraseña es el token de autenticación del dispositivo . Utilice la que anotó cuando registró el dispositivo.
  • username: El nombre de usuario es la cadena de caracteres literal use-token-auth
  • typeid: typeid es el tipo de dispositivo que utilizó cuando registró el dispositivo. En el ejemplo, utilice proximidad.
  • organization: Utilice el ID de su organización.

Escriba una aplicación de Node-RED para sentir la señal del Bluetooth y encender un aparato eléctrico

El cliente MQTT envía la fuerza de la señal del Bluetooth en intervalos regulares al servicio de Internet of Things Platform de Bluemix. Ahora, es necesario escribir una aplicación en Bluemix para procesar esos valores. Utilizamos Node-RED como entorno para crear esa aplicación.

Crear la aplicación de Node-RED y conectar el dispositivo

Primero, conectaremos nuestro dispositivo y nos aseguraremos de que está recibiendo mensajes.

  1. En su aplicación de Bluemix IoT, haga clic en el enlace empezar a escribir código que está en el panel de navegación de la izquierda.
  2. En la parte superior de la pantalla, encuentre el URL de su aplicación en ejecución. Haga clic en ese URL.
  3. Haga clic en el gran botón rojo para abrir su editor de flujos de Node-RED.
  4. En el editor de flujos se muestra una aplicación de muestra. Seleccione todos los elementos del flujo y bórrelos.
  5. Arrastre un nodo de entrada ibmiot al espacio de trabajo y configúrelo haciendo doble clic en él. Utilice el Token de Autenticación de la API que creó anteriormente para conseguir acceder a los datos de su dispositivo, como se muestra en la ilustración de abajo.
  6. Seleccione Todos para tipo de dispositivo, ID de dispositivo, eventoy formato.
  7. Para probar su dispositivo, inicie el cliente del dispositivo en su sistema Linux. Asegúrese de que se envían algunos mensajes a Watson IoT Platform.
    [root@traumcloud btclient]# ./dwclient
    [2015-08-18 17:16:39] trying to use ./dwclient.cfg for configuration
    [2015-08-18 17:16:39] got option 'btmac' with arg 00:0A:3A:2B:C6:ED
    [2015-08-18 17:16:39] got option 'subscription' with arg iot-2/cmd/switch/fmt/+
    [2015-08-18 17:16:39] got option 'host' with arg e62whi.messaging.internetofthings.ibmcloud.com
    [2015-08-18 17:16:39] got option 'password' with arg R3!1sFY(846HRCC0P6
    [2015-08-18 17:16:39] got option 'username' with arg use-token-auth
    [2015-08-18 17:16:39] got option 'typeid' with arg proximity
    [2015-08-18 17:16:39] got option 'organisation' with arg e62whi
    [2015-08-18 17:16:39] got MAC address of this machine as 'b827eb2fa78a'@  eth0
    [2015-08-18 17:16:39] now setting username and password to use-token-auth/*************
    [2015-08-18 17:16:39] now connection using host=e62whi.messaging.internetofthings.ibmcloud.com port=1883
    [2015-08-18 17:16:39] log cb: 'Client d:e62whi:proximity:b827eb2fa78a sending CONNECT'
    [2015-08-18 17:16:40] log cb: 'Client d:e62whi:proximity:b827eb2fa78a received CONNACK'
    [2015-08-18 17:16:40] conn cb 0 'Connection Accepted.'
    [2015-08-18 17:16:40] log cb: 'Client d:e62whi:proximity:b827eb2fa78a sending SUBSCRIBE (Mid: 1, Topic: iot-2/cmd/switch/fmt/+, QoS: 0)'
    [2015-08-18 17:16:40] log cb: 'Client d:e62whi:proximity:b827eb2fa78a sending PUBLISH (d0, q0, r0, m2, 'iot-2/evt/status/fmt/json', ... (31 bytes))'
    [2015-08-18 17:16:40] log cb: 'Client d:e62whi:proximity:b827eb2fa78a received SUBACK'
    [2015-08-18 17:16:40] sub cb 1 subscriptions
    [2015-08-18 17:16:41] BT MQTT msg '{ "d": {"lq":235,"rssi":-13}}'
    [2015-08-18 17:16:41] log cb: 'Client d:e62whi:proximity:b827eb2fa78a sending PUBLISH (d0, q0, r0, m3, 'iot-2/evt/status/fmt/json', ... (29 bytes))'
    [2015-08-18 17:16:46] BT MQTT msg '{ "d": {"lq":250,"rssi":-13}}'
    [2015-08-18 17:16:46] log cb: 'Client d:e62whi:proximity:b827eb2fa78a sending PUBLISH (d0, q0, r0, m4, 'iot-2/evt/status/fmt/json', ... (29 bytes))'
  8. Arrastre un nodo de salida de depuración a su hoja de trabajo y conéctelo al ibmiot .
  9. Haga clic en Desplegar.
  10. Haga clic en la pestaña Depurar de la derecha para ver cómo entran los mensajes de depuración.
  11. Mueva su dispositivo Bluetooth hacia adelante y hacia atrás y verifique que cambian los valores min/max de RSSI.

Escribir la aplicación Node-RED para procesar los datos del dispositivo Bluetooth

Después de verificar que su dispositivo está conectado, puede escribir la aplicación de Node-RED.

  1. Comenzamos con una función de inicio. Arrastre a su espacio de trabajo un nodo de Inyectar, un nodo de función y un nodo de salida de depuración, y conéctelos en esta secuencia.
  2. Configure el nodo Inyectar con carga útil vacía, seleccione inyectar una vez en el inicio, y dé al nodo un nombre que tenga sentido (por ejemplo, AppSetup ).
  3. Configure el nodo función con el siguiente código y dele un nombre que tenga sentido. Tiene que dar un valor a rssimin que esté entre los valores mínimo y máximo que usted descubrió anteriormente para su dispositivo Bluetooth.
    	// Relacionado con el bluetooth
    context.global.bttime=0;
    context.global.rssimin=-32;
    context.global.rssi=0;
    context.global.inBeacon=false;
    	
    // Relacionado con el temporizador
    context.global.lastCmd="";
    context.global.nextSwitch=0;
    context.global.delay=30*1000; // 30 segundos
    
    	// será usado posteriormente con el gps
    	context.global.gpstime=0;
    	context.global.gps={lat: 0.0, lng:0.0};
    	context.global.inFence=true;
    	msg.payload="Aplicación iniciada";
    	return msg;
  4. Configure el nodo Depurar para que su salida vaya a msg.payload y dele un nombre que tenga sentido.
  5. Despliegue el código. Debería ver un mensaje de "Aplicación iniciada" en la pestaña Depurar .
  6. Arrastre a su espacio de trabajo un nodo inyectar , un nodo de entrada ibmiot , dos nodos función , un nodo de salida ibmiot , y un nodo depuración .
  7. Configure el primer nodo función con este código:
     	context.global.rssi=msg.payload.d.rssi
    	context.global.inBeacon=context.global.rssi>context.global.rssimin;
    	return msg;
  8. Configure el segundo nodo función con el código de abajo:
    	//
    // determina cuándo enviar un comando de conmutación
    // Se envía un comando cuando acaba el periodo de gracia
    // desde el último conmutador (para proteger
    // el aparato) y si hay que cambiar el estado
    // del aparato
    now = Date.now();
    dbg={ payload:""};
    var cmd=(context.global.inBeacon &&
     context.globalinFence)?"on":"off";
    if (now > context.global.nextSwitch && 
     context.global.lastCmd != cmd) {
     // tenemos que conmutar ahora
     context.global.nextSwitch+=now+context.global.delay;
     context.global.lastCmd=cmd;
     msg.payload=cmd;
     dbg.payload="switch appliance '"+cmd+"'";
    } else {
     msg=null
     dbg.payload="sin conmutación en el aparato";
    }
    return [ msg, dbg ];
  9. Configure el nodo ibmiot como en la imagen de abajo.
  10. Finalmente, junte los nodos con conexiones:

Probar la aplicación de Node-RED

  1. Despliegue su aplicación. Debería ver el mensaje de "Aplicación iniciada".
  2. Para probar el flujo, si su dispositivo todavía no está conectado, haga clic en el nodo sello de tiempo para inyectar un mensaje. Si su dispositivo está conectado, debería haber mensajes periódicos que digan "sin conmutación en el aparato".
  3. Acerque y aleje lentamente el dispositivo Bluetooth de su sistema Linux y verá los mensajes de depuración del intento de encender y apagar el aparato. Al mismo tiempo, debería ver los comandos encendido y apagado que están llegando al programa cliente que se ejecuta en su Raspberry Pi, y la llamada al script que está configurado para encender o apagar el ventilador, la luz o el aire acondicionado (A/C). Sea consciente de que hay una tasa límite de un conmutador por cada 30 segundos; tal vez quiera disminuir el parámetro context.global.delay para probarlo.

Añada un flujo para que la aplicación de Node-RED acepte y procese los datos del GPS

Hasta ahora, hemos creado una aplicación que enciende un aparato basándose en la proximidad de un dispositivo Bluetooth. Después, mejoraremos la aplicación para que determine cuándo encender el aparato utilizando ubicación geográfica específica proporcionada por un dispositivo GPS.

Aunque los dispositivos GPS actuales se comunican utilizando multitud de protocolos, para este tutorial y aplicación de muestra, asumo que el GPS envía solicitudes HTTP con el par de latitud y longitud como carga útil de un mensaje.

Crear un extremo HTTP para el dispositivo GPS

En su editor de flujos de Node-RED, arrastre un nodo de entrada HTTP a su espacio de trabajo. Haga doble clic en él para configurarlo con estos valores:

  • Método:POST
  • URL:/gps
  • Nombre: GPS Input [POST] /gps

Este nodo HTTP acepta solicitudes POST en este URL: http://dwexample-iot.mybluemix.net/gps. Los datos del POST están disponibles en el flujo de Node-RED como un objeto de mensaje. Los valores de la latitud y la longitud del dispositivo GPS se procesan de nuevo contra la geovalla.

El control de los aparatos mediante la geolocalización no está ligado a una ubicación en particular. Usualmente, el control se lleva a cabo al entrar por dejar una geovalla definida. La valla de nuestra aplicación está representada como un arreglo de pares de latitud y longitud de un objeto JSON, cómo este:

[
    {"lat":43.7074340290373,"lng":7.28219747543335},
	…
	…	
    {"lat":43.705196002070636,"lng":7.284321784973145},
    {"lat":43.706995349373884,"lng":7.284793853759766}
]

Recuperar la geovalla de las bases de datos de Cloudant

El arreglo de los pares de latitud y longitud se almacena en una base de datos Cloudant que forma parte de Internet of Things Platform Starter que utilizamos para crear nuestra aplicación. Si en su aplicación no existe un servicio de base de datos de Cloudant, vaya al catálogo de Bluemix, encuentre el servicio Cloudant NoSQL DB y cree un servicio.

Al recibir un mensaje con las coordenadas GPS, nuestra aplicación necesita recuperar la definición de la valla de la base de datos y luego determinar si la ubicación enviada recientemente está dentro o fuera de la valla. El nodo de la base de datos ignora el elemento de la carga útil del mensaje, así que necesitamos guardar temporalmente el cuerpo de la solicitud HTTP. Para esta solicitud HTTP utilizamos como almacén temporal los atributos globales de Node-RED.

En su editor de flujos de Node-RED, añada un nodo función y añádale el siguiente código JavaScript:

context.global.gps=msg.payload;
context.global.gpstime=Date.now();
msg.save=msg.payload;
msg.payload="valla";
return msg;

La consulta de la base de datos actual se realiza por un nodo Cloudant de la sección de almacenamiento de la paleta. Arrastre hacia la izquierda el nodo con la nube, que es la consulta de Cloudant.

Configure el nodo con estos valores:

  • Servicio: <-nombre-de-su-aplicación>
  • Base de datos: tsldemo
  • Buscar por: _id
  • Nombre: Recuperar la Valla

Determinar si las coordinadas del GPS están dentro de la geovalla

La salida del nodo Cloudant alimenta otro nodo función , en el que un fragmento de código JavaScript determina si las coordenadas GPS están dentro o fuera de la valla. El algoritmo se toma del repositorio point-in-polygon de substack en GitHub. El nodo función registra el estado de la interfaz en un miembro de estructura global.

La salida del nodo función alimenta esos nodos:

  • Un nodo respuesta HTTP que devuelve el estado adecuado a los dispositivos GPS
  • Un nodo que junta las mediciones del Bluetooth con el seguimiento GPS

Este nodo que implementa la función activar el A/C si el GPS está dentro de la valla o el automóvil está lo suficientemente cerca del sensor Bluetooth, pero si la última comunicación fue al menos <n>minutos antes. Al añadir la última condición, la aplicación evita encender o apagar el A/C en intervalos cortos mientras se está conduciendo el automóvil en los límites de la valla. El que código implementa la función es similar al siguiente:

//
//  determina cuándo enviar un comando de conmutación
// Se envía un comando cuando acaba el periodo de gracia
// desde el último conmutador (para proteger
// el aparato) y si hay que cambiar el estado
// del aparato
now = Date.now();
var cmd=(context.global.inBeacon ||
 context.global.inFence)?"on":"off";
if (now > context.global.nextSwitch && 
 context.global.lastCmd != cmd) {
 // necesitamos conmutar ahora
 context.global.nextSwitch=now+context.global.delay;
 context.global.lastCmd=cmd;
 msg.payload=cmd;
 msg.format="text";
} else {
 msg=null
}
return msg;

La aplicación de Node-RED final se parece al flujo Figura 2. Los nodos gris oscuro y gris claro son los que usted creó en los primeros pasos 1 — 4.

Figura 2. Aplicación de Node-RED final

Verificar las funciones de la geovalla

Hagamos una prueba sencilla de las funciones de la geovalla enviando con un comando de curl algunas coordinadas GPS simuladas.

  1. En el panel de información de Bluemix, haga doble clic en su servicio Cloudant DB.
  2. Haga clic en Iniciar para abrir el panel de información de su base de datos de Cloudant:
  3. Introduzca un documento nuevo en el panel de información de su base de datos:
    	"_id": "valla",
      "valla": "[{\"lat\":50.945,\"lng\":6.955},{\"lat\":50.946,\"lng\":6.957},{\"lat\":50.943,\"lng\":6.962},{\"lat\":50.940,\"lng\":6.962}]"
  4. Haga clic en Guardar para almacenar el documento.
  5. Pruebe el flujo de Node-RED con dos coordenadas de GPS simuladas (un par lat/lng que está dentro de la valla y un par lat/lng que está claramente fuera de la valla) mediante la emisión de este comando de curl (y especificando el nombre de su aplicación de muestra):
    	curl -XPOST -d 'lat=1&lng=26' dwexample-iot.mybluemix.net/gps
    	{
    	  "bttime": 0,
    	  "rssimin": -32,
    	  "rssi": 0,
    	  "inBeacon": false,
    	  "lastCmd": "on",
    	  "nextSwitch": 1447771815039,
    	  "delay": 5000,
    	  "gpstime": 1447771815841,
    	  "gps": {
    	    "lat": "1",
    	    "lng": "2"
    	  un},
    	  "inFence": false,
    	}

    Revise los mensajes de la pestaña depuración en su editor de flujos de Node-RED.

    [root@traumcloud btclient]# ./dwclient
    trying to use ./dwclient.cfg for configuration
    got option 'btmac' with arg 00:0A:3A:2B:C6:ED
    got option 'subscription' with arg iot-2/cmd/switch/fmt/+
    [2015-11-17 18:42:25] got option 'host' with arg e62whi.messaging.internetofthings.ibmcloud.com
    got option 'password' with arg R3!1sFY(846HRCC0P6
    got option 'username' with arg use-token-auth
    got option 'typeid' with arg proximity
    got option 'organisation' with arg e62whi
    got MAC address of this machine as 'b827eb2fa78a'@  eth0
    now setting username and password
    log cb:received PUBLISH (d0, q0, r0, m0, '...'
    msg cb topic='iot-2/cmd/switch/fmt/text' payload='on'
    set state of switch2 to on
    log cb: 'Client received PUBLISH (d0, q0, r0, m0, '...'))'
    msg cb topic='iot-2/cmd/switch/fmt/text' payload='off'
    set state of switch2 to off

Añada un panel de información para la valla GPS y establezca un umbral para la baliza

Hasta el momento hemos controlado el A/C obteniendo la ubicación del automóvil de dos maneras diferentes:

  • Detectando una baliza Bluetooth ubicada en el estacionamiento o garaje
  • Realizando un seguimiento del automóvil por sus coordenadas GPS

Ahora, en nuestra aplicación de muestra, todavía tenemos que gestionar esos dos dispositivos de aproximación. Necesitamos establecer el umbral para la baliza y definir la valla de una forma más realista. Para gestionar estos dispositivos, añadiremos una página web que es una UI de administración y añadiremos dos flujos nuevos a nuestra aplicación de back-end que devuelvan los valores operativos actuales o un conjunto de valores operativos nuevos. Vea Figura 3.

Figura 3. Un panel de instrumentos para la sensibilidad del Bluetooth y la visualización del GPS

El diagrama de secuencias Figura 4 representa los componentes y sus interacciones que son necesarios para crear el panel de instrumentos. El panel de información soporta estos casos de uso:

  • Monitoreo continuo de las coordenadas GPS y de la sensibilidad del Bluetooth
  • Editar y cambiar la sensibilidad del Bluetooth
  • Editar y cambiar la geovalla

El panel de instrumentos se implementa como una página HTML y utiliza una solicitud Ajax para obtener datos de la aplicación back-end. Las líneas de la vida de la izquierda Figura 4 están implementadas en Node-RED como flujos.

Figura 4. Un panel de instrumentos para la sensibilidad del Bluetooth y la visualización del GPS

Crear la página web del panel de instrumentos

Para construir el panel de instrumentos puede descargar los archivos que necesita desde el repositorio car-meets-home de GitHub. Importará estos archivos a su aplicación Bluemix IoT.

  1. En su panel de instrumentos de Bluemix, selecciones su aplicación IoT y haga clic en Editar Código.

    Se abren los servicios Bluemix DevOps. La primera vez que hace clic en él pueden tardar un rato, ya que le genera un proyecto nuevo.

  2. En la barra de navegación de la izquierda, identifique la carpeta pública. Haga clic en la carpeta pública y seleccione Importar.
  3. En el diálogo que se abre, navegue hasta el archivo dash.html y haga clic en Abrir. El archivo dash.html aparece debajo del directorio público.
  4. Haga clic derecho de nuevo en la carpeta pública y seleccione Nueva > Carpeta. Dé un nombre a la carpeta nueva js.
  5. Haga clic derecho en la carpeta js e importe dash.js .
  6. Haga clic derecho en la carpeta css e importe dash.css .
  7. Haga clic derecho en la carpeta images e importe los archivos .png.

    Estos archivos forman parte de la aplicación del panel de instrumentos. Puede utilizar su panel de instrumento anexando /dash.html a la ruta de su aplicación (por ejemplo, <su nombre>.mybluemix.net/dash.html).

Añadir APIs al flujo para atender las solicitudes de Ajax

Para que el panel de instrumentos funcione, necesitamos añadir algunas APIs a nuestro flujo de Node-RED. El panel de instrumentos obtiene el estado de la aplicación back-end con una solicitud HTTP-GET a /status. De igual manera, el valor rssimin (la sensibilidad) se envía con una solicitud HTTP-POST a /status. La geovalla se recupera por una GET a /fence, mientras que la valla se almacena con una POST a /fence.

Cree los flujos y añada el código a las funciones:

  1. Añada los flujos para la recuperación y la actualización del estado, como se muestra en la imagen de abajo:
  2. Añada el siguiente código al nodo llamado Añadir global como carga útil:
    msg.payload=context.global;
    msg.payload.jt=Date.now();
    return msg;
  3. El siguiente código JavaScript de la página web toma los valores del Bluetooth y del GPS y los muestra en formato de texto, gráficamente como un medidor de metros para los valores del Bluetooth y como posición en un mapa para los valores del GPS. Las principales líneas de código para mostrar los datos son:
    	    //
    	    // obtener el estado y los métodos para mostrar
    	    //
    	    this.getData=function () {
    		 	$.ajax({url: "/status",
    		 	 	success: thiz.getDataOK,
    		 	 	error: thiz.getDataErr,
    		 	 	dataType: "json"
    		 	});
    		 	window.setTimeout(thiz.getData, 5000);
    	    };
    	    this.getDataOK=function (data) {
    		 	//console.dir(datos);
    		 	if (olddata == null) olddata=data;
    	
    		 	car.setLatLng(L.latLng(data.gps.lat, data.gps.lng));
    		 	map.panTo(L.latLng(data.gps.lat, data.gps.lng));
    	
    		 	$('#bt-rssi').text(data.rssi+"/"+data.lq);
    		 	$('#bt-rssimin').text(data.rssimin);
    		 
    		 	$('#time').text(new Date().toLocaleString());
    		 	thiz.drawRssiMeter(data);
    		 	olddata=data;
    	
    	    };
    	    this.drawRssiMeter=function (data) {
    		 	var rssi=Math.floor(data.rssi||-50);
    		 	var rssimin=Math.floor(data.rssimin||-50);
    		 	var min = Math.min(rssimin, rssi);
    		 	var max = Math.max(rssimin, rssi);
    	
    		 	var rssiMeterData = new google.visualization.DataTable();
    	
    		 	rssiMeterData.addColumn('number', 'Rssi');
    		 	rssiMeterData.addColumn('number', 'lq');
    		 	rssiMeterData.addRows(2);
    		 	rssiMeterData.setCell(0, 0, rssi);
    	
    		 	rssiMeterOptions.min=min-15;
    	 	 	rssiMeterOptions.max=max+5;
    		 	 	 	 
    		 	rssiMeterOptions.greenFrom=rssimin;
    		 	rssiMeterOptions.yellowTo=rssimin;
    	  	 	// dibuja el espacio para el mínimo de amarillo a mitad amarillo, mitad rojo
    		 	var step=Math.floor(Math.abs(rssimin-rssiMeterOptions.min)/2);
    		 	rssiMeterOptions.yellowFrom=rssimin-step;
    		 	rssiMeterOptions.redTo=rssimin-step;
    	
    		 	rssiMeterOptions.redFrom=Math.min(min,rssimin)-2*step;
    		 	 
    		 	rssiMeter.draw(rssiMeterData, rssiMeterOptions);
    	    };
  4. El panel de información contiene algunas líneas de código más, que causan que los valores se muestren en rojo entre los sondeos de datos.

    El botón llamado "Introducir el nuevo valor para el mínimo de RSSI" toma los valores introducidos para el RSSI y envía los datos a la Node-RED API.

        this.getDataErr=function (xhr, sts, txt) {
    	    thiz.error("Ajax Error: sts='"+sts+"', txt='"+txt+"'");
        };
        //
        // Actualiza la sensibilidad del bluetooth
        //
        this.setRssiVal=function() {
    	 	var url="/status";
    	 	$.ajax({url: url,
    	 	 	success: thiz.getDataOK,
    	 	 	error: thiz.getDataErr,
    	 	 	method: "POST",
    	 	 	data: {rssimin: $('#rssid-val-text').val().trim()},
    	 	 	dataType: "json"
    	 	 	});
        };
  5. La API de Node-RED establece el valor del RSSI (sensibilidad del Bluetooth) en la estructura de variables locales.
    if (msg.payload.rssimin) context.global.rssimin=msg.payload.rssimin;
    msg.payload=context.global;
    return msg;
  6. De la misma manera, puede añadir elementos de la UI para el tiempo de retardo entre las operaciones de conmutación, establecerlos para los flujos iguales a rssimin.

    Añada flujos para recuperar los datos de la geovalla como se muestra en la siguiente imagen:

        var storeFence=function() {
        	var ll=fence.getLatLngs();
    	 	var data={ fence: JSON.stringify(ll) };
    	 	if (fencers._id !== undefined) data._id=fencers._id;
     	 	if (fencers._rev !== undefined) data._rev=fencers._rev;
    	 	// subir a bluemix
    	 	$.ajax({
    	 	 	url: "/fence2",
    	 	 	data: data,
      	 	 	contenttype: "application/json",
    	 	 	method: "POST",
    	 	 	/**
    	 	 	 * @callback
    	 	 	 */
    	 	 	success: function( data ) {
    	 	 	 	$('#upload').show();
    	 	 	 	window.setTimeout(function() {
    	 	 	 	 	$('#upload').fadeOut(2000);
    	 	 	 	}, 2000);
    	 	 	 	loadFence(); // para actualizar _rev
    	 	 	}
    	 	});
    	};
  7. La carga de la geovalla se implementa de dos métodos, el primero para llamar de forma asíncrona a la API de Node-RED API y el segundo como función de devolución de la llamada. La geovalla se carga cuando la aplicación se inicia o cuando el usuario pulsa cargar .
    var loadFence=function() {
    	// carga la definición de la valla desde bluemix
    	//
    	$('#download').show();
    	$.ajax({
    	 	url: "/fence",
    	 	contenttype: "application/json",
    	 	method: "GET",
    	 	success: function( data ) {
    	 	 	$('#download').fadeOut(1000);
    	 	 	$('#received').fadeIn(1000);
    	 	 	window.setTimeout(function() {
    	 	 	 	$('#received').fadeOut(1000);
    	 	 	}, 2000);
    	 	 	loadFenceOK(data);
    	 	},
    	 	error: function(a, b) {
    	 	 	thiz.error("No se pueden cargar los datos de la valla, razón dada: '"+a+"':'"+b+"'");
    	 	}
    	});
    };
    var loadFenceOK=function(data) {
        var ll=[];
        var i;
        fencers=data;
        if (data.fence) {
            ll=JSON.parse(data.fence);
    	    for (i=0; i<ll.length; i++) {
    	 	L.marker([ll[i].lat, ll[i].lng], {icon: reddot}).addTo(map).on('click', removeDot);
    	    }
    	}
    	fence=L.polygon(ll, {color: 'red'}).addTo(map);
    	//
    	// mapa de posición para encajar el automóvil y la valla en la ventana de navegación
    	//
    	ll=fence.getLatLngs();
    	var b=L.latLngBounds(ll);
    	b.extend(car.getLatLng());
    	map.fitBounds(b, {animate: true, duration: 2.0});
    	$('#save').prop( "disabled", ll.length <= 2 );
    	$('#load').prop( "disabled", false);
    };
  8. Además, el panel de instrumentos contiene un editor de geovallas básico. Si hace clic en un punto del mapa, el punto se añade al polígono y define el área de la geovalla. Si hace clic en uno de los puntos rojos, el punto se elimina del polígono de la geovalla.
    1. Para eliminar el punto del polígono, un bucle compara las coordenadas de las coordenadas del polígono con las coordenadas del ícono creado con Leaflet. Si coinciden, el punto se quita del polígono.
          //
            // editor de vallas (muy básico)
          //
          var removeDot=function(me) {
      	 	var ll=fence.getLatLngs();
      	 	var i, l=ll.length;
      	 	for (i=0; i<l; i++) {
      	 	 	var p=ll[i];
      	 	 	var dx=p.lat-me.latlng.lat; // distancia desde un punto en la valla a la posición del mapa en la que hizo clic
      	 	 	var dy=p.lng-me.latlng.lng;
      	 	 	if (dy === 0 || dx === 0) {
      	    		fence.spliceLatLngs(i, 1);
      	    		l--;
      	    		break;
      	 	 	}
      	 	}
      	 	 
      	 	map.removeLayer(me.target);	// borra el punto en el que ha hecho clic;
      	 	$('#save').prop( "disabled", l <= 2 );
      
          };
    2. Para añadir el punto al polígono hace falta un poco más de esfuerzo, ya que el código tiene que encontrar los puntos del polígono que son mejores para añadir en medio el punto nuevo. La aplicación del panel de información ejecuta los siguientes pasos:
      • Encontrar el punto más próximo a las coordenadas del punto en el que hizo clic en el mapa.
      • Desde los dos vecinos, determinar el más cercano al punto del mapa.
      • Introducir el punto nuevo entre los dos puntos encontrados.

      El código de JavaScript que se ocupa de polígonos (casi) vacíos y del estado del botón guardar, se parece al código siguiente:

      var addDot=function(me) {
          	// ve qué punto ya existente está cerca del evento me del ratón como p1
          	// encuentra los nodos adyacentes de p1 que sean más cercanos a me
          	// introduce me entre ellos
          	var ll=fence.getLatLngs();
          	var i, l=ll.length;
          	var p0=me.latlng, p1=null, p2=null;
          	if (l < 2) {
          	 	// Hay solo un punto (o ninguno) en la valla, simplemente hay
      que agregar uno nuevo 	 	fence.addLatLng([ok, good, me.latlng.lng]);
          	} else {
          	 	var dist=0x07ffffff;	// signo int de 32bit máx
      	    	var p, dlat, dlng;
      	    	var d=Math.sqrt(dlat*dlat+dlng*dlng);
      	    	for (i=0; i<l; i++) {
      	    		p=ll[i];
      	    		dlat=p0.lat-p.lat;
      	    		dlng=p0.lng-p.lng;
      	    		d=Math.sqrt(dlat*dlat+dlng*dlng);
      	    		if (d < dist) {
      	    			p1=i;
      	    			dist=d;
      	    		}
      	    	}
      	    	// encuentra el adyacente más cercano
          	 	p2=(p1+l-1)%l;
          	 	p=ll[p2];
          	 	dlat=p0.lat-p.lat;
          	 	dlng=p0.lng-p.lng;
      	    	dist=Math.sqrt(dlat*dlat+dlng*dlng);
      	    	
          	 	p=ll[(p1+l+1)%l];
          	 	dlat=p0.lat-p.lat;
           	 	dlng=p0.lng-p.lng;
      	    	d=Math.sqrt(dlat*dlat+dlng*dlng);
      	    	if (d < dist) p2=(p1+l+1)%l;
      	    	console.log("add dot @"+p1+"/"+p2);
      	    	if (p1 > p2) { var t=p1; p1=p2; p2=t;}
      	    	// caso especial: p1 son p2 el principio y el fin de un arreglo
        	    	if (p1 === 0 && p2 === l-1) {
      	    		fence.addLatLng(p0);
      	    	} else {
      	    		fence.spliceLatLngs(p2, 0, p0);
      	    	}
          	}
      	L.marker(me.latlng, {icon: reddot}).addTo(map).on('click', removeDot);
      	$('#save').prop( "disabled", l+1 <= 2 );
          };

      Observe que el punto del polígono se implementa como un Ícono de Leaflet con una devolución de llamada que se desencadena cuando el usuario hace clic en el ícono. Como consecuencia, el punto se elimina del polígono y el ícono asociado se elimina del mapa. Este código le permite determinar fácilmente si el clic de un usuario es para añadir o para eliminar un punto del polígono de la geovalla.

Es posible ver la demo del panel de información ejecutándose en Bluemix:
http://car-meets-home.mybluemix.net/.

Conclusión

En este tutorial, aprendió cómo crear una aplicación de Bluemix, registrar un Raspberry Pi a Watson IoT Platform, obtener acceso a los datos del dispositivo y escribir una aplicación de Node-RED para procesar los datos que están viniendo mediante la utilización del protocolo MQTT.

En el Raspberry Pi, usted creó un cliente MQTT que puede informar de la fuerza de la señal del Bluetooth y recibir comandos de su aplicación de Bluemix.

Extendimos la aplicación básica de forma rápida y fácil, para añadir nuevas funciones como recibir coordenadas GPS desde un dispositivo externo, decidir cuando activar aparatos basándonos en una combinación de la fuerza de la señal Bluetooth y de la ubicación geográfica dentro o fuera de una geovalla definida. Y finalmente, hemos creado incluso un panel de instrumentos para definir la geovalla para que funcione el control GPS y para establecer la sensibilidad del sensor Bluetooth. Las funciones se añadieron como APIs con tan solo unos nodos extras en la aplicación Node-RED.

Ahora, muestre su inteligencia y conecte su automóvil a su casa.


Recursos para Descargar


Comentarios

Inicie Sesión o Regístrese para agregar comentarios.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=Internet of Things
ArticleID=1036220
ArticleTitle=Lleve el IoT a su casa: conecte su automóvil hacia su casa
publish-date=08162016