Azure IoT Hub es un servicio de mensajería pensado para conectar dispositivos IoT con la nube de forma segura y escalable.
En los artículos anteriores ya hemos visto Wi-Fi, HTTP, JSON y MQTT. Ahora vamos a juntar todas esas piezas para que nuestro ESP32 con nanoFramework pueda enviar telemetría real a Azure, sin montar nosotros todo el protocolo MQTT a mano.
IoT Hub no es “una API REST más”. Está pensado para dispositivos: autenticación por dispositivo, mensajes hacia la nube, mensajes desde la nube, gemelos digitales, métodos directos y aprovisionamiento.
Qué necesitamos
Para este ejemplo necesitamos tener preparado:
- Un Azure IoT Hub creado en Azure.
- Un dispositivo registrado dentro del IoT Hub.
- El nombre del host del IoT Hub, por ejemplo
mi-hub.azure-devices.net. - El Device ID del dispositivo.
- La Primary Key o Secondary Key del dispositivo, no la connection string completa.
En nanoFramework usaremos el paquete NuGet nanoFramework.Azure.Devices.Client, que expone la clase DeviceClient.
No confundas la clave del dispositivo con la clave compartida del servicio. Para un ESP32 que se conecta como dispositivo, usa la clave de ese dispositivo concreto.
Conectar con DeviceClient
La clase DeviceClient encapsula la conexión MQTT contra Azure IoT Hub. Le damos el host, el identificador del dispositivo y la clave SAS, y ella se encarga de construir la conexión correctamente.
using System.Diagnostics;
using nanoFramework.Azure.Devices.Client;
public class Program
{
private const string IotHub = "mi-hub.azure-devices.net";
private const string DeviceId = "esp32-salon";
private const string SasKey = "CLAVE_DEL_DISPOSITIVO";
public static void Main()
{
DeviceClient client = new DeviceClient(IotHub, DeviceId, SasKey);
if (client.Open())
{
Debug.WriteLine("Conectado a Azure IoT Hub");
}
else
{
Debug.WriteLine("No se pudo conectar a Azure IoT Hub");
}
}
}Esto presupone que ya tenemos Wi-Fi y hora correcta. Si el reloj del dispositivo está mal, TLS y los tokens SAS fallarán, porque los certificados y firmas dependen del tiempo.
Antes de abrir DeviceClient, conecta el Wi-Fi con WifiNetworkHelper.ConnectDhcp(..., requiresDateTime: true, ...). Así te aseguras de tener IP y fecha válida.
Enviar telemetría
La telemetría no deja de ser un mensaje que el dispositivo envía hacia la nube. Lo habitual es enviarla en JSON, porque es fácil de leer, de procesar y de almacenar.
using System.Diagnostics;
using System.Threading;
using nanoFramework.Azure.Devices.Client;
public class Program
{
private const string IotHub = "mi-hub.azure-devices.net";
private const string DeviceId = "esp32-salon";
private const string SasKey = "CLAVE_DEL_DISPOSITIVO";
public static void Main()
{
DeviceClient client = new DeviceClient(IotHub, DeviceId, SasKey);
if (!client.Open())
{
Debug.WriteLine("No se pudo conectar a Azure IoT Hub");
Thread.Sleep(Timeout.Infinite);
}
while (true)
{
string payload = "{ \"temperature\": 23.7, \"humidity\": 48 }";
bool sent = client.SendMessage(payload, "application/json");
Debug.WriteLine(sent
? "Telemetría enviada"
: "Error enviando telemetría");
Thread.Sleep(30000);
}
}
}Para una prueba rápida está bien escribir el JSON a mano. En un proyecto real, lo normal es construirlo desde un objeto o una pequeña función que centralice el formato.
Certificados y TLS
Azure IoT Hub usa conexiones seguras. Eso significa que el dispositivo debe confiar en el certificado raíz correspondiente.
En nanoFramework podemos pasar el certificado raíz mediante el parámetro azureCert, o tenerlo ya cargado en el dispositivo si hemos preparado el firmware y los recursos para ello.
byte[] azureRootCertificate = Resources.GetBytes(Resources.BinaryResources.AzureRoot);
DeviceClient client = new DeviceClient(
IotHub,
DeviceId,
SasKey,
azureCert: azureRootCertificate);Si la conexión falla sin un mensaje demasiado amable, revisa primero tres cosas: hora correcta, certificado raíz y clave del dispositivo. En IoT, el 80% de los “misterios” viven ahí.
Propiedades de usuario
Además del cuerpo del mensaje, IoT Hub permite enviar propiedades. Son metadatos útiles para enrutar mensajes, aplicar reglas o filtrar telemetría.
Por ejemplo, podemos marcar un mensaje como alert = true cuando la temperatura supera un umbral.
using System.Collections;
using nanoFramework.Azure.Devices.Client;
using nanoFramework.M2Mqtt;
ArrayList properties = new ArrayList();
properties.Add(new UserProperty("alert", "true"));
properties.Add(new UserProperty("sensor", "dht22"));
client.SendMessage(
"{ \"temperature\": 61.2 }",
"application/json",
properties);Esto nos permite hacer reglas en la nube sin tener que abrir y parsear todos los JSON.
Qué aporta frente a MQTT directo
Podríamos conectarnos a IoT Hub usando MQTT manualmente. De hecho, por debajo ocurre algo parecido. La diferencia es que DeviceClient ya conoce las convenciones de Azure:
- Construcción correcta del client ID y usuario MQTT.
- Gestión de SAS keys o certificados.
- Envío de mensajes con el formato esperado por IoT Hub.
- Acceso a Twin, propiedades reportadas y métodos directos.
Es decir, no estamos perdiendo control. Estamos evitando escribir una capa de pegamento que suele ser aburrida y fácil de romper.