Desarrollo de apps IoT: dispositivos y nube
Construir una app que habla con un dispositivo físico, un wearable, un sensor, una máquina, un producto inteligente, se siente como construir una app normal hasta que deja de sentirse así. De pronto lidias con conexiones inestables, dispositivos que duermen para ahorrar batería, firmware que hay que actualizar en campo, y la realidad incómoda de que un dispositivo hackeado es una cosa hackeada en la casa o el trabajo de alguien. Este artículo es la arquitectura que mantiene un producto IoT confiable y seguro: cómo llegan los datos del dispositivo a la nube, cómo la app sigue siendo útil cuando la red no coopera, cómo un dispositivo demuestra quién es, cómo actualizas una flota sin inutilizarla, y cuánto cuesta en realidad la conexión permanente que todos dan por sentada.
Las tres capas, y los dos saltos entre ellas
Todo sistema IoT tiene la misma forma: el dispositivo (el hardware y su firmware), la nube (donde los datos aterrizan, se guardan y se actúa sobre ellos) y la app (donde una persona lo ve y lo controla todo). El trabajo de diseño vive en los dos saltos entre ellas, porque ninguno es una conexión limpia y siempre encendida. El salto de dispositivo a nube está limitado por energía y cobertura; el salto de nube a app es una API común hasta que la persona que la usa entra a un sótano. Decide temprano qué capa es dueña de cada decisión: un termostato debe mantener la casa caliente con la nube inalcanzable, y una cerradura debe abrirse para un teléfono autorizado sin señal alguna. Control local para todo lo que toque la seguridad; nube para la historia, la coordinación y todo lo que abarque varios dispositivos.
Patrones de dispositivo a nube
Hay tres formas comunes de que un dispositivo llegue a internet, y la elección la hacen sobre todo el presupuesto de energía y el lugar donde vive el dispositivo.
| Patrón | Cómo se conecta | Encaja cuando | Cuidado con |
|---|---|---|---|
| El teléfono como pasarela (BLE) | El dispositivo habla Bluetooth Low Energy con la app; el teléfono retransmite a la nube | Wearables, sensores pequeños, cualquier cosa que una persona carga o tiene al lado | Sin teléfono no hay datos. El emparejamiento, la reconexión y el fuera de alcance son toda la experiencia |
| Directo a la nube (Wi-Fi o celular) | El dispositivo sostiene su propia conexión, normalmente MQTT sobre TLS hacia un broker | Productos enchufados, vehículos, equipos que deben reportar sin nadie cerca | Aprovisionar el Wi-Fi; costo de datos celulares; consumo de una radio persistente |
| Hub o pasarela local | Los dispositivos usan una malla de bajo consumo (Thread, Zigbee, BLE) hacia un hub que tiene el enlace | Muchos dispositivos por sitio: edificios, fincas, plantas, casas con decenas de sensores | Un producto más que aprovisionar y actualizar; el hub es un punto único de fallo |
Para el salto por red, el lenguaje común es MQTT: un protocolo ligero de publicación y suscripción hecho para muchos dispositivos pequeños en enlaces poco confiables, y por eso domina el IoT donde HTTP a secas sería demasiado pesado. Un dispositivo publica lecturas en un tema como site/42/device/7/telemetry y se suscribe a un tema de comandos; el broker (un servicio IoT administrado o el tuyo) reparte los mensajes a los servicios de backend que los necesiten. Dos características de MQTT importan más de lo que parece. Los niveles de calidad de servicio te dejan elegir por mensaje si “enviar y olvidar” basta (una lectura de temperatura) o si la entrega debe confirmarse (un comando de abrir una puerta). Y el mensaje de última voluntad, que el broker publica en nombre del dispositivo si la conexión muere, es cómo la nube se entera de que un dispositivo se apagó sin tener que consultarlo. Nuestro concepto PulseAI usa el primer patrón, un teléfono emparejado con un reloj inteligente por BLE; los equipos industriales suelen usar el segundo o el tercero.
BLE para el salto de teléfono a dispositivo de cerca; MQTT para el flujo de dispositivo a nube a escala. La mayoría de los productos usa ambos, y la app debe ser honesta sobre cuál está funcionando en este momento.
Telemetría sin ahogar a nadie
La telemetría es la manguera de lecturas que suben: temperatura, ubicación, estado, batería. El truco es enviar lo suficiente para ser útil sin agotar la batería ni tu backend. Los dispositivos deben agrupar y espaciar, no parlotear: muestrear seguido, transmitir poco, enviar de inmediato un cambio de estado y el estado estable en un latido lento. Ponle una marca de tiempo a cada lectura en el dispositivo, porque va a llegar tarde, fuera de orden o en ráfaga después de una reconexión, y la nube debe guardarla según cuándo ocurrió y no cuándo aterrizó. El patrón de sombra del dispositivo (también llamado gemelo digital) resuelve el problema del espejo: la nube mantiene un documento con el último estado reportado del dispositivo y su estado deseado, la app lee y escribe ese documento, y el dispositivo se sincroniza con él cuando puede. La app entonces nunca espera al hardware: fija “deseado: cerrado” y muestra un indicador pendiente hasta que “reportado: cerrado” lo alcanza. El mismo enfoque de transmisión desde el servidor que usamos para el mapa en vivo de Vexolis, camiones que reportan hacia arriba y despachadores que miran hacia abajo, aplica a cualquier flota de cosas; las opciones de transporte están en nuestra guía de apps en tiempo real.
Sincronización offline-first en la app
La conectividad nunca está garantizada, y la persona que sostiene el teléfono suele estar en el peor lugar para tenerla: un piso de planta, un sótano, un campo, la cabina de un camión. Un buen sistema lo asume. Del lado del dispositivo, significa guardar las lecturas en local y sincronizar cuando vuelve el enlace. Del lado de la app, significa que la app es cliente de su propia base de datos local primero y de la nube después: cada pantalla lee datos locales, cada acción escribe en local y se encola para subir, y un motor de sincronización concilia en segundo plano. Así funciona exactamente Leak Survey Sidekick, porque los rincones de una planta donde se esconden las fugas de aire comprimido son los rincones donde muere la señal, así que un técnico registra la fuga en el dispositivo y se sube cuando regresa a la cobertura. El mismo patrón sostiene nuestro concepto de bodega Stowly.
Los detalles que separan un modo offline que funciona de un demo:
- Ids generados en el cliente. Un registro creado sin conexión necesita identidad antes de que el servidor lo haya visto, así que la app acuña un UUID y el servidor lo acepta, lo que además hace que cada subida sea segura de reintentar.
- Una bandeja de salida, no un bucle de reintentos. Los cambios encolados viven en una tabla, sobreviven a un reinicio de la app y se drenan en orden; un fallo en uno se guarda con su error en lugar de bloquear al resto.
- Una política de conflictos elegida por campo. Que gane la última escritura está bien para una nota y es peligroso para un estado; en los campos que importan, conserva ambas versiones y deja que el servidor o un humano decida.
- Interfaz honesta. Muestra “última sincronización hace 14 minutos” y “3 cambios en espera” en lugar de fingir que todo está en vivo. Los usuarios perdonan la latencia; no perdonan una pérdida silenciosa.
Aprovisionamiento e identidad
El aprovisionamiento es la primera impresión sin glamour: poner un dispositivo recién sacado de la caja en la red del usuario y vincularlo a su cuenta. Es el momento en que la mayoría de los productos se siente mágico o roto, así que merece atención de diseño real y, en silencio, es también donde se decide la seguridad. Los flujos comunes son la configuración asistida por BLE, donde la app le envía las credenciales de Wi-Fi al dispositivo por Bluetooth; un punto de acceso temporal al que se une el teléfono; y un código QR en el dispositivo que lleva su identidad para que la app pueda reclamarlo. Elijas lo que elijas, el usuario nunca debería teclear una contraseña de Wi-Fi en un teclado diminuto en el dispositivo, y la configuración debe sobrevivir a que la interrumpan a la mitad.
La regla de identidad es absoluta: cada dispositivo recibe su propia credencial, nunca una contraseña compartida horneada en el firmware, porque una sola imagen filtrada compromete entonces a toda la flota. La versión fuerte es un certificado por dispositivo, idealmente generado dentro de un elemento seguro en la fábrica para que la llave privada nunca exista en otro lugar, con la nube validándolo en cada conexión y capaz de revocar un dispositivo sin tocar al resto. Reclamar vincula esa identidad de dispositivo a una cuenta de usuario, y desvincular en una reventa debe borrar la asociación y los datos locales. La nube autoriza entonces por identidad, no por confianza: un dispositivo puede publicar solo en sus propios temas, y una app puede comandar solo los dispositivos que su cuenta posee. Es el mismo pensamiento de privilegio mínimo que aplicamos a cualquier servidor expuesto, con la diferencia de que aquí una brecha abre una puerta o apaga una bomba.
Actualizar la flota sin inutilizar nada
Las actualizaciones de firmware por aire no son negociables. Vas a lanzar errores y a encontrar agujeros de seguridad, y un dispositivo que no puedes actualizar es un pasivo desde el día siguiente a su lanzamiento. Hacerlo con seguridad es una lista en la que todos los productos maduros convergen:
- Imágenes firmadas. El dispositivo verifica una firma antes de instalar cualquier cosa, así que solo acepta firmware genuino, aunque el canal de descarga esté comprometido.
- Particiones A/B. La imagen nueva se escribe en una segunda ranura y el dispositivo arranca desde ella; si no logra reportarse a la nube después de arrancar, el gestor de arranque regresa solo a la ranura anterior. Una reversión que necesita a un humano no es reversión.
- Despliegue escalonado. Uno por ciento de la flota, luego diez, luego todos, con una métrica de salud (tasa de reporte, informes de fallos, batería) como compuerta en cada paso. Una imagen mala descubierta al uno por ciento es un incidente; al cien es un retiro del mercado.
- Actualizaciones diferenciales y programadas. Envía solo los bytes que cambiaron, y deja que el dispositivo actualice cuando esté cargado y ocioso, nunca en plena operación.
- Un piso de versión. La nube debe saber el firmware mínimo con el que hablará, para que un dispositivo que durmió un año se actualice antes de hacer cualquier otra cosa.
La app necesita su propia versión de esta disciplina: firmware, API de nube y app evolucionan a velocidades distintas, y la app en el bolsillo de alguien puede tener un año. Versiona cada mensaje, mantén la API compatible hacia atrás y nunca asumas que las tres capas se lanzaron juntas.
El costo de la conectividad permanente
“Está conectado” es una característica en la caja y una factura recurrente en todos los demás lados, y los dueños de producto subestiman con regularidad adónde se va el dinero. Está la partida obvia: planes de datos celulares por dispositivo, y mensajería en la nube cobrada por mensaje o por minuto de conexión, lo que premia agrupar y castiga el parloteo. Luego las menos obvias. Energía: una radio persistente es el mayor consumo en un dispositivo a batería, así que un diseño siempre conectado puede convertir un año de batería en semanas, y la solución son ciclos de sueño y despertar por evento, que la nube y la app deben entonces tolerar. Almacenamiento: la telemetría se acumula para siempre a menos que la reduzcas, conservando segundos por una semana, minutos por un año y agregados por hora de ahí en adelante. Soporte: cada dispositivo que se desconecta genera un ticket, así que el estado honesto de “visto por última vez” en la app también es un control de costos. Y la cola más larga, el propio servicio en la nube: el dispositivo en la repisa seguirá intentando conectarse dentro de cinco años, así que el backend, sus certificados y sus versiones de protocolo tienen que sobrevivir al ciclo del producto, y eso tiene que estar en el presupuesto de alguien. Diseña la conectividad como un recurso que se gasta a propósito, no como una suposición de fondo, y muchos productos descubren que un reporte cada hora le sirve al usuario exactamente igual que un enlace en vivo.
Un marco de decisión que corres en una tarde
- ¿Dónde vive el dispositivo y qué lo alimenta? Batería y una persona cerca significa BLE a través del teléfono; enchufado y sin supervisión significa directo o a través de un hub.
- ¿Qué debe funcionar con la nube caída? Todo lo que toque la seguridad se decide en local.
- ¿Qué tan frescos deben ser los datos? Elige la cadencia de reporte antes que el protocolo; define batería, costo y carga del backend.
- ¿Cómo demuestra un dispositivo quién es? Credenciales por dispositivo, revocables de una en una, o el diseño no está terminado.
- ¿Qué pasa cuando una actualización falla a las 3 de la mañana? Imágenes firmadas, ranuras A/B, reversión automática, despliegue escalonado.
- ¿Qué muestra la app sin señal? Datos locales, cambios en cola, hora de la última sincronización, nada de fingir.
- ¿Quién paga el backend en el año cinco? Nombra la partida ahora.
En resumen
El IoT es desarrollo de apps normal más la física desordenada del mundo real: conexiones intermitentes, dispositivos limitados y apuestas físicas en lugar de digitales. Diseña para el modo sin conexión desde el principio, elige el protocolo correcto para cada salto, haz del aprovisionamiento y las actualizaciones por aire ciudadanos de primera, dale a cada dispositivo su propia identidad, y trata la conectividad como un costo que gastas a propósito. Con eso bien hecho, el producto se siente sin esfuerzo para el usuario. Los productos conectados están en la intersección de las apps móviles y los sistemas a medida que construimos. Si estás uniendo hardware y software, cuéntanos, o mira lo que hemos construido.
Preguntas frecuentes
¿Cómo envía datos a la nube un dispositivo IoT?
Tres patrones comunes. Un dispositivo a batería cerca de una persona habla Bluetooth Low Energy con el teléfono, que retransmite a la nube. Un dispositivo enchufado o sin supervisión sostiene su propia conexión Wi-Fi o celular, normalmente MQTT sobre TLS hacia un broker. Muchos dispositivos en un mismo sitio usan una malla de bajo consumo como Thread o Zigbee hacia un hub que tiene el enlace. MQTT domina el salto por red porque es ligero, ofrece garantías de entrega por mensaje y permite que el broker anuncie la desconexión de un dispositivo mediante un mensaje de última voluntad.
¿Qué significa offline-first en una app IoT?
Que la app es cliente de su propia base de datos local primero y de la nube después. Cada pantalla lee datos locales, cada acción escribe en local y se encola en una bandeja de salida, y un motor de sincronización concilia en segundo plano cuando vuelve la conectividad. Los detalles que importan son ids generados en el cliente para que los registros sin conexión tengan identidad y las subidas sean seguras de reintentar, una política de conflictos elegida por campo, y una interfaz honesta que muestre la hora de la última sincronización y cuántos cambios esperan, en lugar de fingir que todo está en vivo.
¿Cómo se deben aprovisionar y autenticar los dispositivos IoT?
El aprovisionamiento pone un dispositivo nuevo en la red del usuario y lo vincula a su cuenta, normalmente mediante configuración asistida por BLE, un punto de acceso temporal o un código QR que lleva la identidad del dispositivo. La regla de seguridad es que cada dispositivo recibe su propia credencial, idealmente un certificado por dispositivo generado en un elemento seguro, para que una imagen de firmware filtrada no comprometa la flota y cualquier dispositivo se pueda revocar por separado. La nube autoriza entonces por identidad: un dispositivo publica solo en sus propios temas y una app comanda solo los dispositivos que su cuenta posee.
¿Cómo se actualiza el firmware de una flota sin inutilizar dispositivos?
Firma cada imagen para que el dispositivo solo instale firmware genuino, escribe la imagen nueva en una segunda partición A/B y revierte automáticamente si el dispositivo no logra reportarse después de arrancar, escalona el despliegue desde el uno por ciento de la flota hacia arriba con una métrica de salud como compuerta en cada paso, envía actualizaciones diferenciales cuando el dispositivo esté cargado y ocioso, y mantén un piso de versión mínima para que un dispositivo que durmió un año se actualice antes de hacer cualquier otra cosa. Una reversión que necesita a un humano no es reversión.
¿Cuánto cuesta la conectividad permanente en un producto IoT?
Más que el plan de datos. La mensajería en la nube se cobra por mensaje o por minuto de conexión, lo que castiga a los dispositivos que parlotean. Una radio persistente es el mayor consumo en un dispositivo a batería y puede convertir un año de autonomía en semanas. La telemetría se acumula para siempre a menos que se reduzca. Cada dispositivo desconectado genera un ticket de soporte. Y el backend, sus certificados y sus versiones de protocolo deben sobrevivir al ciclo del producto, porque los dispositivos en las repisas seguirán conectándose dentro de cinco años. Muchos productos descubren que un reporte cada hora le sirve al usuario igual que un enlace en vivo.
¿Qué decisiones debería tomar el dispositivo en local en lugar de la nube?
Todo lo que toque la seguridad. Un termostato debe mantener la casa caliente con la nube inalcanzable y una cerradura debe abrirse para un teléfono autorizado sin señal alguna. La nube es dueña de la historia, la coordinación y todo lo que abarque varios dispositivos, y el patrón de sombra del dispositivo mantiene a ambos consistentes: la nube guarda el último estado reportado y el estado deseado, la app lee y escribe ese documento, y el dispositivo se sincroniza con él cuando puede.
¿Estás pensando en construir esto?
Appluex diseña y lanza apps móviles y web en producción, incluidas funciones de inteligencia artificial. Hablemos.