¿Te interesa aprender a montar una operación de IoT en la nube totalmente administrada, con auto-escalado y serverless?
En esta serie de tres entregas, IoT en GCP, recorreremos un flujo de IoT completo: desde el registro de dispositivos hasta el streaming y el almacenamiento a largo plazo de los datos, además de su análisis y visualización.

Buenas prácticas de IoT a escala productiva
Al terminar la Parte Uno, sabrás cómo registrar de forma segura millones de dispositivos IoT que transmiten datos de telemetría a tu entorno de Google Cloud.
Esta es la primera entrega de una serie de tres partes:
- El almacenamiento y la visualización adecuados de estos flujos de datos de alto rendimiento se abordan en la Parte Dos, y
- La construcción de un modelo de machine learning funcional sobre datos IoT se aborda en la Parte Tres.
A lo largo de la serie usaremos GCP como proveedor de nube y dispositivos Raspberry Pi con sensores de temperatura como ejemplo de dispositivos IoT.
Visión general
Esta guía está dividida en las siguientes secciones:
- Configuración de software y hardware del Raspberry Pi
- Registro de dispositivos paso a paso y aprovisionamiento de credenciales
- Pruebas de conectividad del dispositivo y streaming de datos de temperatura
- Limitaciones de la funcionalidad de Google Cloud IoT
- Almacenamiento de datos en streaming (se aborda en la Parte Dos)
- Visualización de datos en streaming (se aborda en la Parte Dos)
- Construcción de un modelo de machine learning eficaz con datos IoT (se aborda en la Parte 3)
Para seguir este artículo solo necesitas experiencia con Bash y Python, y un conocimiento básico de la Google Cloud Console.
Configurar software y hardware del Raspberry Pi
Primero, pon en marcha varios Raspberry Pi — yo usaré dispositivos Pi 3. Te recomiendo usar el Raspbian OS Imager para automatizar la instalación del sistema operativo en las tarjetas microSD.
Instalar los paquetes de Python
Una vez que llegues al escritorio y actualices el dispositivo, ejecuta el siguiente comando para instalar el SDK específico de Google Cloud IoT:
pip3 install -U pyjwt paho-mqtt
Antes de continuar, conviene entender por qué instalamos paho-mqtt en lugar del SDK general de Google Cloud para Python google-api-python-client. Tanto el SDK de Python más usado como la CLI gcloud de GCP funcionan sobre HTTP. Ese protocolo es útil para ejecutar la mayoría de las acciones de forma rápida, pero no resulta adecuado para enviar mensajes a través de conexiones de larga duración con alta probabilidad de conectividad intermitente, en las que los datos fluyen principalmente desde el dispositivo hacia afuera.
MQTT es un protocolo utilizado en IoT, mediante paquetes como paho-mqtt, porque está diseñado para que un dispositivo pueda publicar mensajes con frecuencia y recibirlos con poca frecuencia, incluso cuando la conectividad es inestable.
Conectar un sensor digital de temperatura
Ahora que tu Raspberry Pi tiene los paquetes de Python necesarios, hay que conectarle un sensor digital de temperatura. Si quieres seguir el artículo al pie de la letra, te recomiendo usar este sensor DS18B20.
También necesitarás lo siguiente para conectar el sensor a tu Raspberry Pi:
- Mini protoboards
- Cables jumper para protoboard
- Kit surtido de resistencias (necesitamos una resistencia de 4.7K Ohm)
Si tienes que esperar a que lleguen estos componentes, sigue leyendo: incluimos un script para hacer streaming de temperaturas simuladas.
Si ya cuentas con los componentes, los primeros cinco minutos de este tutorial te muestran cómo conectar el sensor a tu Raspberry Pi y comprobar que recibe valores de temperatura.
Además del proceso descrito en ese tutorial, recomiendo añadir lo siguiente a /etc/modules para que los módulos onewire se carguen al arrancar, en lugar de tener que ejecutar modprobe después de cada reinicio:
w1-gpio
w1-therm
Registrar tus dispositivos IoT
A continuación verás un ejemplo completo y funcional de cómo configurar tu IoT Registry con dispositivos registrados de forma segura, desde los cuales transmitiremos datos de temperatura a la plataforma Google Cloud IoT.
Crear un registro para tus dispositivos
En la Google Cloud Console:
- Crea un nuevo proyecto (por ejemplo, "IoTTempStreaming")
- Entra al servicio IoT Core para habilitar la API de IoT
- Haz clic en "Create registry" para crear un registro al que agregar tus dispositivos IoT.
Los dispositivos IoT que transmiten datos a GCP pueden mandar sus mensajes a IoT Core siempre que se validen como dispositivos con credenciales almacenados en el IoT Registry, así que crear el registro es un primer paso esencial.

Un entorno IoT Core recién creado, a la espera de recibir mensajes
Crear un topic de Pub/Sub
Los mensajes que llegan a IoT Core — junto con metadatos críticos del mensaje, como el deviceId único del dispositivo — se reenvían internamente a un "topic" en Pub/Sub, el sistema de cola de mensajes de Google Cloud, totalmente administrado, con auto-escalado y serverless.
Por eso, también crearemos topics de Pub/Sub desde el propio formulario del IoT Registry, de modo que nuestros datos de telemetría terminen llegando a Pub/Sub para su procesamiento posterior.
Sigue estos pasos para crear un topic de Pub/Sub desde el formulario del IoT Registry:
- Asigna a tu Registry ID el nombre "RaspberryPiDevices" en la región us-central1
- Crea un topic de Pub/Sub llamado "sensordata", al que llegarán por defecto los mensajes de telemetría IoT.
- En "Additional topics", crea un nuevo topic de Pub/Sub llamado "temperature", al que llegarán los mensajes publicados en una subcarpeta del topic IoT — también llamada "temperature".
Esta configuración garantiza que solo los mensajes de temperatura publicados en una subcarpeta IoT específica lleguen al topic de Pub/Sub temperature, y que cualquier otro evento de telemetría (inesperado) caiga en el topic por defecto "sensordata".
También recomiendo desplegar las opciones avanzadas y permitir únicamente el protocolo MQTT, desmarcando HTTP:

Configuración del IoT Core Registry para transmitir datos de sensores de temperatura
Después de crearlo, tu registro debería verse así:

Una configuración exitosa del IoT Core Registry
Crear un dispositivo registrado
Ahora que tenemos un registro de dispositivos, vamos a crear un dispositivo registrado.
Para empezar, necesitaremos (1) un par de claves pública-privada asociado al dispositivo y (2) el certificado raíz de Google.
A continuación se detallan los comandos a ejecutar en un Raspberry Pi para generar claves de Curva Elíptica y obtener el certificado raíz de Google (los comandos se basan en la documentación correspondiente de Google Cloud). Las claves EC ocupan menos espacio que las claves RSA tradicionales y ayudan a los dispositivos IoT a mantener un rendimiento óptimo en zonas con conectividad limitada:
$ mkdir -p /home/pi/GCP/iot_keys/
$ cd /home/pi/GCP/iot_keys/
$ wget http://pki.goog/roots.pem
$ openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem
$ openssl ec -in ec_private.pem -pubout -out ec_public.pem
$ cat ec_public.pem
$ cd ../
Una vez que ejecutes los comandos anteriores:
- Copia la clave pública que se muestra en la terminal
- Ve al IoT Registry y entra a Devices
- Haz clic en Add Device
- Asigna un nombre al dispositivo (por ejemplo, "device1") y pega tu clave pública ES256 en Authentication, como se muestra abajo.
- Haz clic en Create

Registro de un dispositivo IoT solicitando una clave de Curva Elíptica
Una vez creado, las credenciales asociadas a un dispositivo registrado en IoT Core ya están listas para usarse en un Raspberry Pi.
Toma nota del Numeric ID asignado al dispositivo, del Project ID y del Registry ID.
Con esos valores, junto con las claves y el certificado raíz de Google en el dispositivo, tenemos que crear un archivo de configuración llamado gcp_iot_config.txt. Ese archivo definirá los detalles de autenticación y del endpoint IoT que usará un dispositivo concreto. Más adelante en el artículo se describe un script de Python que transmite valores de temperatura usando este archivo de configuración:
$ pwd
/home/pi/GCP/
$ cat gcp_iot_config.txt
# Set the path to the location containing your keys
KEY_PATH = /home/pi/GCP/iot_keys/# Specify the private key and Google root cert names
PRIVATE_KEY = ec_private.pem
GOOGLE_ROOT_CERT = roots.pem# Set the details required for using your IoT endpoint
REGISTRY_ID = <REGISTRY_ID>
DEVICE_ID = <DEVICE_NUMERIC_ID>
REGION = us-central1
PROJECT_ID = <PROJECT_ID>
¡Y listo! Tu dispositivo ya está preparado para enviar de forma segura datos de telemetría a un topic de Pub/Sub a través de la plataforma de autenticación IoT Core de GCP. Repite el proceso anterior para generar credenciales únicas y registrar cada nuevo dispositivo.
Probar la conectividad del dispositivo
Vamos a probar la conectividad del dispositivo ejecutando el siguiente script, llamado "publish_temps.py", que transmite valores de temperatura reales del dispositivo o simulados, según comentes la línea 107 o la 108.
(El script es una adaptación de dos scripts de ejemplo de Google Cloud: #1 y #2)
$ pwd
/home/pi/GCP/
$ ./publish_temps.py
Aquí ocurren bastantes cosas — recomiendo revisar el código para entender mejor cómo se conecta y transmite los datos de forma segura.
Al ejecutar este script, deberías ver una salida parecida a esta:

Valores reales de temperatura enviados a GCP IoT Core vía MQTT
Si ejecutas este script al arrancar mediante un trabajo de crontab (precedido por un sleep de 30s para que los módulos onewire se carguen al inicio), tu dispositivo IoT retomará el streaming en caso de un reinicio (esperado o no):
$ crontab -e
@reboot sleep 30 && /home/pi/GCP/publish_temps.py -c /home/pi/GCP/gcp_iot_config.txt >> /home/pi/GCP/publish_temps.log 2>&1
Repite los procesos de onboarding y streaming en todos los Raspberry Pi distribuidos por tu casa. ¡Vas por buen camino para trabajar con datos IoT a escala!
Verificar que los datos se están transmitiendo
Verifiquemos rápidamente que los mensajes están llegando a Google Cloud, revisando los datos de telemetría que aterrizan en Pub/Sub.
- Crea una suscripción de Pub/Sub al topic "temperature"
- Entra a la suscripción
- Haz clic en View Messages y selecciona el botón de radio Pull
Deberías ver los mensajes a medida que llegan, con la información de temperatura y timestamp incluida en el cuerpo del mensaje, además de los metadatos de atributo que identifican de manera única qué dispositivo envía esos valores. Esos metadatos no solo sirven para la analítica y los dashboards de usuarios finales, sino también para identificar y bloquear dispositivos abusivos o comprometidos.

Creación de una suscripción de Pub/Sub para visualizar los mensajes de telemetría de temperatura entrantes
Así se ve una suscripción al topic temperature:

Visualización de mensajes en una suscripción de Pub/Sub al topic "temperature"
Después de hacer clic en "PULL", deberías empezar a ver los mensajes y sus atributos:

Datos de temperatura llegando a un topic de Pub/Sub y a una suscripción de Pub/Sub: cuerpo del mensaje

Datos de temperatura llegando a un topic de Pub/Sub y a una suscripción de Pub/Sub: atributos identificadores únicos
Si llegaste hasta aquí, ¡felicidades (en serio)! Aunque emociona ver datos reales de dispositivos IoT llegando a Pub/Sub, apenas hemos rascado la superficie.
Para sacarle partido de verdad a estos datos, hace falta transformarlos (de forma opcional), moverlos o cargarlos por lotes a un data warehouse y analizarlos. Todo eso debe ocurrir sobre un ecosistema de servicios de GCP que permita que el flujo de datos funcione de forma confiable, a escala y con buenos costos, en todas las etapas del desarrollo: desde las pruebas iniciales hasta el uso en producción a escala de petabytes y más allá, todo con poco o ningún mantenimiento de infraestructura. Si quieres ver cómo se hace, no te pierdas las partes dos y tres.
Próximamente: almacenamiento y visualización
No te pierdas la Parte Dos, donde hablaré de los servicios adecuados de ETL, almacenamiento y visualización que permiten, con relativa facilidad, sacar provecho práctico de datos IoT en streaming a gran escala.
Limitaciones de la funcionalidad de Google Cloud IoT
Mejor manejo del deviceId por parte de los servicios totalmente administrados de GCP
Quizá hayas notado que el script de Python envía un par clave:valor device_id en el cuerpo del mensaje, lo que en realidad duplica el atributo deviceId presente en el mensaje de Pub/Sub que IoT Core asigna a partir de la asociación del mensaje con el par clave-valor único del dispositivo emisor.
¿Por qué hago que el script envíe un device_id que podría falsificarse fácilmente en un dispositivo comprometido y terminar contaminando un data warehouse cuando estos mensajes pasen al almacenamiento a largo plazo?
Bueno, me estoy adelantando un poco, pero como veremos en la Parte Dos existe un flujo de trabajo conveniente, totalmente administrado, con auto-escalado y prácticamente serverless, que puede transformar y mover mensajes de Pub/Sub a BigQuery usando Dataflow, la versión totalmente administrada de Apache Beam de Google Cloud.
Por desgracia, la plantilla por defecto "Pub/Sub-to-BigQuery" escrita por GCP y disponible en Dataflow no ofrece ningún mecanismo para mover los atributos del mensaje a BigQuery; solo puede moverse el contenido del cuerpo del mensaje. Confirmé con varios ingenieros de GCP que no es posible escribir una UDF personalizada en JavaScript para Dataflow sobre sus plantillas por defecto que añada los atributos del mensaje a destinos de Dataflow como BigQuery. La alternativa, escribir trabajos de Dataflow en Java — ya sea desde cero o como modificación de las plantillas existentes de GCP —, es una tarea que consume mucho tiempo y exige mantener y actualizar la plantilla de forma continua, algo que imagino que la mayoría de los clientes de GCP no querrá asumir.
Por lo tanto, por defecto no hay una forma sencilla y segura de asociar un mensaje IoT que llega a Pub/Sub y se canaliza hacia destinos de datos con el deviceId de ese mensaje.
Le he planteado este descuido a GCP y, desde entonces, han abierto una solicitud pública de funcionalidad para que las plantillas por defecto admitan el paso de estos valores tan valiosos — y absolutamente necesarios — para soportar el caso de uso de IoT. Actualizaré el artículo en cuanto se cumpla esa FR, pero hasta entonces, con fines de demostración, es mucho más fácil probar el uso de device_id enviándolo en el cuerpo del mensaje que reescribir una plantilla de Dataflow que debería estar disponible por defecto.
¿Cómo aprovisionaría idealmente credenciales únicas por dispositivo?
El proceso para registrar un solo dispositivo IoT suele explicarse así:
- Crear un par de claves pública-privada asociado en GCP con permisos de IoT
- Aprovisionar y colocar estos archivos en el dispositivo en la fábrica
- Hacer que la fábrica registre esas credenciales en el IoT Registry
- Habilitar el par de claves para hacer llamadas a la API de IoT que transmitan datos a la nube.
Sin embargo, esa configuración por sí sola no es ideal, porque los casos de uso reales de IoT involucran millones de dispositivos transmitiendo a un entorno en la nube. Cada dispositivo de una flota así debe tener un conjunto único de credenciales, de modo que si un dispositivo o sus credenciales de Google Cloud se ven comprometidos y se usan con fines ilegítimos, ese conjunto pueda deshabilitarse sin afectar al resto de los dispositivos de la flota.
GCP tiene esta funcionalidad y, como se ve en el script anterior, también permite restringir un dispositivo a publicar únicamente en un topic exclusivo de ese dispositivo. Sin embargo, dadas las metodologías de aprovisionamiento de credenciales disponibles, coordinar la creación, despliegue y registro de claves para millones de dispositivos es todo un reto.
¿Cómo se puede simplificar al máximo el proceso de creación de credenciales específicas por dispositivo? ¿Se puede hacer sin crear millones de certificados por adelantado y coordinar su colocación única en los dispositivos durante la fabricación? ¿Quieres depender de un fabricante para que coloque estos archivos de manera fiable y sin duplicarlos?
Como alternativa, ¿se puede registrar y credencializar el dispositivo sin obligar al fabricante a hacer llamadas a la API de tu IoT Registry para crear nuevas credenciales bajo demanda cuando un dispositivo recorre la línea de producción para inicializarse con software y credenciales? ¿Qué pasa con la línea de producción si se cae la conexión con tu API Gateway que da soporte al registro IoT?
Preferiría evitar estos métodos porque son más complejos, propensos a errores y suponen una carga innecesaria para el fabricante.
Un sistema de registro de dispositivos seguro y razonablemente escalable que me gustaría ver soportado por GCP seguiría estas pautas:
- Se crea un único certificado IoT que se coloca en todos los dispositivos IoT. Ese certificado, llamado certificado "bootstrap", estaría asociado a una política de permisos que solo permitiera al dispositivo emitir una solicitud para (a) crear y obtener credenciales específicas del dispositivo si se aprueba la solicitud, y (b) agregarse a sí mismo al IoT Registry de dispositivos.
- La plataforma GCP IoT Core, al recibir y aprobar la solicitud de creación de credenciales, generará un nuevo par de claves. Los permisos IoT asociados — como ya hace Google Cloud — solo deberían permitir al dispositivo publicar mensajes en un topic exclusivo de ese dispositivo.
- La creación de credenciales únicas por dispositivo debería estar condicionada a un paso de validación. Sería una Cloud Function escrita por ti que requiera identificadores únicos en la solicitud para poder cotejarlos contra una whitelist (por ejemplo, una lista de números de serie fabricados o direcciones MAC en uso) y/o una blacklist (por ejemplo, una lista de números de serie asociados a dispositivos comprometidos, abusivos o ya registrados).
- Si la solicitud de certificado único del dispositivo se aprueba en el paso de validación, el dispositivo se incorpora al IoT Registry y los nuevos archivos de credenciales se entregan al dispositivo para usarlos en el streaming de datos.
Con este flujo, un fabricante de dispositivos IoT solo tendría que entregar a cada dispositivo el certificado bootstrap. El par de claves único del dispositivo, que habilita el streaming de datos, podría crearse y obtenerse al instante dentro de la planta de producción, si así se desea, o más tarde, una vez que el dispositivo esté en manos del usuario final.
Independientemente de cuándo se obtengan las credenciales, el fabricante simplemente cargaría en el dispositivo el software que tú proporciones, el cual ejecuta el proceso de creación del par de claves único basado en el certificado bootstrap cuando:
- El dispositivo arranca
- Hay una conexión a Internet disponible, y
- Se detecta que falta el par de claves único del dispositivo
Lamentablemente, esa funcionalidad todavía no existe. Pero más allá del registro masivo de dispositivos, la oferta IoT de Google Cloud — combinada con servicios de procesamiento de mensajes totalmente administrados (que se abordan en la Parte Dos) — constituye en su conjunto una solución sólida, segura y fácilmente escalable, respaldada por la nube, en el ámbito de IoT.