Utilice el archivo de demostración ./demos/subdev_basic_demo.c del Link SDK en C para llamar a las API del Link SDK y conectar un subdispositivo a IoT Platform mediante una puerta de enlace.
Contexto
Para obtener más información sobre las puertas de enlace y los subdispositivos, consulte Overview.
-
La puerta de enlace del subdispositivo debe mantener una conexión persistente con IoT Platform. El método de conexión es el mismo que se usa para un dispositivo conectado directamente. Para obtener más información, consulte MQTT connection overview.
En este ejemplo, la información de autenticación de identidad del dispositivo de puerta de enlace es la siguiente:
ProductKey
DeviceName
DeviceSecret
a18wP
LightSwitchGW
uwMTmVAMnGGHaAkqmeDY6cHxxB
Paso 1: Inicialización
-
Agregue el archivo de encabezado.
…… …… #include "aiot_subdev_api.h" -
Configure las dependencias subyacentes y la salida de registros.
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile); aiot_state_set_logcb(demo_state_logcb); -
Llame a aiot_subdev_init para crear una instancia de cliente
subdeve inicializar los parámetros predeterminados.subdev_handle = aiot_subdev_init(); if (subdev_handle == NULL) { printf("aiot_subdev_init failed\n"); demo_mqtt_stop(&mqtt_handle); return -1; }
Paso 2: Configurar las funciones
Llame a aiot_subdev_setopt para configurar las siguientes funciones.
-
Asocie el handle de la conexión MQTT.
ImportanteAntes de configurar los parámetros de las funciones de la puerta de enlace y del subdispositivo, compruebe que ya configuró la información de autenticación de identidad de la puerta de enlace. Para obtener más información, consulte Configure connection parameters for MQTT.
-
Código de ejemplo:
aiot_subdev_setopt(subdev_handle, AIOT_SUBDEVOPT_MQTT_HANDLE, mqtt_handle); -
Parámetros:
Elemento de configuración
Ejemplo
Descripción
AIOT_SUBDEVOPT_MQTT_HANDLE
mqtt_handle
Las funciones de la puerta de enlace y del subdispositivo dependen de la conexión MQTT. Utilice este elemento de configuración para asociar el handle de la conexión MQTT.
-
-
Configure las devoluciones de llamada de mensajes para las funciones de la puerta de enlace y del subdispositivo.
-
Configure la función de devolución de llamada de mensajes.
-
Código de ejemplo:
aiot_subdev_setopt(subdev_handle, AIOT_SUBDEVOPT_RECV_HANDLER, demo_subdev_recv_handler); -
Parámetros:
Elemento de configuración
Valor de ejemplo
Descripción
AIOT_SUBDEVOPT_RECV_HANDLER
demo_subdev_recv_handler
Cuando el dispositivo recibe mensajes de puerta de enlace o de subdispositivo desde IoT Platform, esta función de devolución de llamada se activa para procesarlos según corresponda.
-
-
Defina la función de devolución de llamada de mensajes.
Para obtener información sobre el formato de datos Alink de los mensajes, consulte Manage topology relationships y Sub-device online and offline status.
void demo_subdev_recv_handler(void *handle, const aiot_subdev_recv_t *packet, void *user_data) { switch (packet->type) { case AIOT_SUBDEVRECV_TOPO_ADD_REPLY: case AIOT_SUBDEVRECV_TOPO_DELETE_REPLY: case AIOT_SUBDEVRECV_TOPO_GET_REPLY: case AIOT_SUBDEVRECV_BATCH_LOGIN_REPLY: case AIOT_SUBDEVRECV_BATCH_LOGOUT_REPLY: case AIOT_SUBDEVRECV_SUB_REGISTER_REPLY: case AIOT_SUBDEVRECV_PRODUCT_REGISTER_REPLY: { printf("msgid : %d\n", packet->data.generic_reply.msg_id); printf("code : %d\n", packet->data.generic_reply.code); printf("product key : %s\n", packet->data.generic_reply.product_key); printf("device name : %s\n", packet->data.generic_reply.device_name); printf("message : %s\n", (packet->data.generic_reply.message == NULL)?("NULL"):(packet->data.generic_reply.message)); printf("data : %s\n", packet->data.generic_reply.data); } break; case AIOT_SUBDEVRECV_TOPO_CHANGE_NOTIFY: { printf("msgid : %d\n", packet->data.generic_notify.msg_id); printf("product key : %s\n", packet->data.generic_notify.product_key); printf("device name : %s\n", packet->data.generic_notify.device_name); printf("params : %s\n", packet->data.generic_notify.params); } break; default: { } } }
-
Paso 3: Agregar una relación de topología
-
Obtenga la información de autenticación del subdispositivo.
Cree un producto y un dispositivo para el subdispositivo. Al crear el producto, establezca el tipo de nodo en Gateway Sub-device. Por ejemplo, cree un producto de subdispositivo y agregue cuatro subdispositivos.
Nombre del producto
ProductKey
DeviceName
DeviceSecret
ProductSecret
LightSwitchSD
a13FN
LightSwitch_SubDev_01
768XBgQwgOakz3K4uhOiLeeh9x
y7GSILD480
LightSwitch_SubDev_02
iwTZrbjbgNVChfuJkihjE5asek
LightSwitch_SubDev_03
fdutq35iKMYdcWWBuIINY26hsN
LightSwitch_SubDev_04
HCKv50YqgwdKhy5cE0Vz4aydmK
Para obtener más información, consulte Create a product y Create a device.
-
Defina la variable
g_subdevpara la información de autenticación del subdispositivo.El código de ejemplo incluye información de autenticación preconfigurada para cuatro subdispositivos. En un entorno de producción, escriba su propio código para recuperar la información de autenticación del subdispositivo. A continuación se muestran algunos ejemplos:
Defina un protocolo entre la puerta de enlace y el subdispositivo que permita a la puerta de enlace descubrir el subdispositivo y obtener su certificado de dispositivo. Los fabricantes de la puerta de enlace y del subdispositivo definen este protocolo.
Como alternativa, el fabricante de la puerta de enlace puede proporcionar un método para preconfigurar la información del certificado del subdispositivo en la puerta de enlace.
aiot_subdev_dev_t g_subdev[] = { { "a13FN******", "LightSwitch_SubDev_01", "768XBgQwgOakz3K4uhOiLeeh9x******", "y7GSILD480******" }, { "a13FN******", "LightSwitch_SubDev_02", "iwTZrbjbgNVChfuJkihjE5asek******", "y7GSILD480******" }, { "a13FN******", "LightSwitch_SubDev_03", "fdutq35iKMYdcWWBuIINY26hsN******", "y7GSILD480******" }, { "a13FN******", "LightSwitch_SubDev_04", "HCKv50YqgwdKhy5cE0Vz4aydmK******", "y7GSILD480******" } }; -
Llame a aiot_subdev_send_topo_add para enviar una solicitud a IoT Platform y agregar una relación de topología entre el subdispositivo y el dispositivo de puerta de enlace.
res = aiot_subdev_send_topo_add(subdev_handle, g_subdev, sizeof(g_subdev)/sizeof(aiot_subdev_dev_t)); if (res < STATE_SUCCESS) { printf("aiot_subdev_send_topo_add failed, res: -0x%04X\n", -res); aiot_subdev_deinit(&subdev_handle); demo_mqtt_stop(&mqtt_handle); return -1; } -
Opcional: Si el dispositivo de puerta de enlace ya no actúa como agente del subdispositivo para recibir mensajes de IoT Platform, llame a aiot_subdev_send_topo_delete para eliminar la relación de topología entre el subdispositivo y el dispositivo de puerta de enlace.
aiot_subdev_send_topo_delete(subdev_handle, g_subdev, sizeof(g_subdev)/sizeof(aiot_subdev_dev_t)); if (res < STATE_SUCCESS) { printf("aiot_subdev_send_topo_delete failed, res: -0x%04X\n", -res); aiot_subdev_deinit(&subdev_handle); demo_mqtt_stop(&mqtt_handle); return -1; }
Paso 4: Iniciar sesión en el subdispositivo
-
Llame a aiot_subdev_send_batch_login para enviar una solicitud a IoT Platform e iniciar sesión en los subdispositivos por lotes. Una vez que los subdispositivos inician sesión mediante la relación de topología establecida, su estado cambia a Online.
aiot_subdev_send_batch_login(subdev_handle, g_subdev, sizeof(g_subdev)/sizeof(aiot_subdev_dev_t)); if (res < STATE_SUCCESS) { printf("aiot_subdev_send_batch_login failed, res: -0x%04X\n", -res); aiot_subdev_deinit(&subdev_handle); demo_mqtt_stop(&mqtt_handle); return -1; } -
Opcional: Para desconectar un subdispositivo, llame a aiot_subdev_send_batch_logout para enviar una solicitud a IoT Platform. Cuando IoT Platform recibe la solicitud, el subdispositivo se desconecta y su estado cambia a Offline.
ImportanteCuando se llama a esta API, IoT Platform actualiza el estado del subdispositivo a desconectado. Esto evita que la puerta de enlace reciba los mensajes destinados al subdispositivo.
aiot_subdev_send_batch_logout(subdev_handle, g_subdev, sizeof(g_subdev)/sizeof(aiot_subdev_dev_t)); if (res < STATE_SUCCESS) { printf("aiot_subdev_send_batch_logout failed, res: -0x%04X\n", -res); aiot_subdev_deinit(&subdev_handle); demo_mqtt_stop(&mqtt_handle); return -1; }
Después de que un subdispositivo inicia o cierra sesión, IoT Platform gestiona los mensajes según el estado del subdispositivo:
Si el subdispositivo está desconectado, los mensajes
QoS=0de IoT Platform hacia el subdispositivo se descartan de inmediato.Si el subdispositivo está conectado, IoT Platform envía los mensajes del subdispositivo a la puerta de enlace correspondiente. Esta última los reenvía al subdispositivo.
Paso 5: Suscribirse a un tema del subdispositivo
Una vez que un subdispositivo se conecta a IoT Platform mediante una puerta de enlace, llame a aiot_mqtt_sub para suscribirse al tema del subdispositivo y recibir sus mensajes.
Al suscribirse a un tema, distinga entre el ProductKey y el DeviceName del subdispositivo y los de la puerta de enlace. Compruebe que se suscribe al tema del dispositivo correcto.
-
Código de ejemplo:
{ char *sub_topic = "/a13FN******/LightSwitch_SubDev_01/user/get"; res = aiot_mqtt_sub(mqtt_handle, sub_topic, NULL, 1, NULL); if (res < 0) { printf("aiot_mqtt_sub failed, res: -0x%04X\n", -res); return -1; } } -
Parámetros:
Parámetro
Ejemplo
Descripción
sub_topic
/a13FN/LightSwitch_SubDev_01/user/get
Un tema al que tiene permisos de suscripción. En este tema:
-
a13FNes el ProductKey del subdispositivo. -
LightSwitch_SubDev_01es el DeviceName del subdispositivo.
Este ejemplo utiliza un tema personalizado predeterminado para que el subdispositivo reciba mensajes de IoT Platform.
Para obtener más información sobre los temas, consulte What is a topic?.
-
Paso 6: Publicar un mensaje desde el subdispositivo
Llame a aiot_mqtt_pub para publicar un mensaje en un tema específico del subdispositivo.
-
Código de ejemplo:
{ char *pub_topic = "/a13FN******/LightSwitch_SubDev_01/user/update"; char *pub_payload = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}"; res = aiot_mqtt_pub(mqtt_handle, pub_topic, (uint8_t *)pub_payload, (uint32_t)strlen(pub_payload), 0); if (res < 0) { printf("aiot_mqtt_sub failed, res: -0x%04X\n", -res); return -1; } } -
Parámetros:
Parámetro
Ejemplo
Descripción
pub_topic
/a13FN/LightSwitch_SubDev_01/user/update
Un tema en el que tiene permisos de publicación. En este tema:
-
a13FNes el ProductKey del subdispositivo. -
LightSwitch_SubDev_01es el DeviceName del subdispositivo.
Este ejemplo utiliza un tema personalizado predeterminado para el subdispositivo. El dispositivo utiliza este tema para publicar mensajes en IoT Platform.
Para obtener más información sobre los temas, consulte What is a topic?.
pub_payload
{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}
El contenido del mensaje que se reporta a IoT Platform.
Dado que la categoría del tema del mensaje de ejemplo es personalizada, el formato de los datos también puede ser personalizado.
Para obtener más información sobre los formatos de datos, consulte Data formats.
-
Paso 7: Desconectar la puerta de enlace
MQTT se suele utilizar en dispositivos que requieren una conexión persistente. Por lo tanto, el programa normalmente no llega a este punto.
En el programa de ejemplo, el hilo principal se encarga de configurar los parámetros y establecer la conexión. Una vez establecida la conexión, el hilo principal puede entrar en hibernación.
Llame a aiot_mqtt_disconnect para enviar un mensaje de desconexión a IoT Platform y desconectarse de la red.
res = aiot_mqtt_disconnect(mqtt_handle);
if (res < STATE_SUCCESS) {
aiot_mqtt_deinit(&mqtt_handle);
printf("aiot_mqtt_disconnect failed: -0x%04X\n", -res);
return -1;
}
Paso 8: Salir del programa
Llame a aiot_subdev_deinit para destruir la instancia de cliente subdev y liberar los recursos asociados.
res = aiot_subdev_deinit(&subdev_handle);
if (res < STATE_SUCCESS) {
printf("aiot_subdev_deinit failed: -0x%04X\n", res);
}
Pasos siguientes
-
Después de configurar el archivo de ejemplo, compílelo para generar el archivo ejecutable ./output/subdev-basic-demo.
Para obtener más información, consulte Compile and run.
Para obtener más información sobre los resultados, consulte Operational logs.