Skip to content

由 wxlinus 贡献,Ai-Thinker 进行整理

【Clion开发】【二】阿里云物联网平台使用之M61开发板连接阿里云平台

经过上面的相关内容我们已经可以连接到阿里云物联网平台了,现在我们就来学习一下如何使用阿里云物联网平台的物模型功能 物模型是阿里云物联网平台为产品定义的数据模型,用于描述产品的功能。

物模型详细的内容添加与新建可以参考官方文档:定义物模型属性、事件和服务_物联网平台(IoT)-阿里云帮助中心 (aliyun.com) 我们下边就讲讲如何使用物模型来点m61开发板上面的灯

灯的定义

c
/*
* RGB灯引脚定义
*/
#define LED3_R 12
#define LED3_G 14
#define LED3_B 15

操作步骤

1
在阿里云物联网平台上新建相关物模型

登录阿里云物联网平台控制台,在产品详情页的「物模型」标签页中定义产品功能(属性、事件、服务),配置完成后发布上线。

物模型属性、事件、服务的 Alink JSON 数据格式和 Topic

2
设备端开发

物模型属性上报:云端会根据上报数据改变设备状态(示例中暂时注释,因为上报频率高会打印太多日志,不利于调试)。

上报的数据会对应到云端的对应物模型属性,详细参考官方文档。例如 LightSwitch 就是把对应标识的物模型数据变为 0{"LightSwitch": 0}

3
编写属性设置解析代码

云端通过 SetDeviceProperty / SetDevicesProperty 下发设置属性指令到设备。相关解析代码主要是判断接收到云端相应消息后进行解析,然后开关灯:

static void rgb_led_dm_set(char *data) {
    if (data == NULL) {
        LOG_E("data is no's json");
    }
    cJSON *root = cJSON_Parse(data);
    if (root == NULL) {
        LOG_E("root is null");
    }
    cJSON *led_r = cJSON_GetObjectItem(root, "LED_R");
    if (led_r != NULL) {
        if (led_r->valueint == 0) {
            led_off(LED3_R);
        } else {
            led_on(LED3_R);
        }
    }
    cJSON *led_g = cJSON_GetObjectItem(root, "LED_G");
    if (led_g != NULL) {
        if (led_g->valueint == 0) {
            led_off(LED3_G);
        } else {
            led_on(LED3_G);
        }
    }
    cJSON *led_b = cJSON_GetObjectItem(root, "LED_B");
    if (led_b != NULL) {
        if (led_b->valueint == 0) {
            led_off(LED3_B);
        } else {
            led_on(LED3_B);
        }
    }
    cJSON_Delete(root);
}
4
状态验证

在云端打开调试页面设置一下属性:

可以看到设备端接收到了对应消息,开发板上的灯也亮了:

5
小结与初始化代码

物模型还有很多功能,比如采集温湿度传感器数据上报到云端,方法都是类似的,只要新建对应的物模型即可。基于物模型还能做数据流转、数据保存、云产品流转、Web 可视化等内容。

设备端物模型相关的函数回调由以下函数实现(本次涉及的是属性设置函数:收到数据后解析,判断对应状态,然后开灯与关灯)。物模型相关 API 作为组件集成到 linksdk 中:

初始化相关代码主要是 MQTT 初始化中以 dm 开头的一些函数,完整代码见下方。

c
uint8_t user_mqtt_init(void) {
    int32_t res = STATE_SUCCESS;
    //安全凭据结构体, 如果要用TLS, 这个结构体中配置CA证书等参数
    aiot_sysdep_network_cred_t cred;
    uint8_t protocol_version = 0;
    //配置SDK的底层依赖
    aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
    //配置SDK的日志输出
    aiot_state_set_logcb(demo_state_logcb);
    //创建SDK的安全凭据, 用于建立TLS连接
    memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
    //使用RSA证书校验MQTT服务端
    cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA;
    //最大的分片长度为16K, 其它可选值还有4K, 2K, 1K, 0.5K
    cred.max_tls_fragment = 16384;
    //TLS建连时, 支持Server Name Indicator
    cred.sni_enabled = 1;
    //用来验证MQTT服务端的RSA根证书
    cred.x509_server_cert = ali_ca_cert;
    //用来验证MQTT服务端的RSA根证书长度
    cred.x509_server_cert_len = strlen(ali_ca_cert);
    //创建1个MQTT客户端实例并内部初始化默认参数
    mqtt_handle = aiot_mqtt_init();
    if (mqtt_handle == NULL) {
        LOG_E("aiot_mqtt_init failed\n");
        return -1;
    }
    // 配置MQTT协议的版本
    protocol_version = AIOT_MQTT_VERSION_5_0;
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_VERSION, (void *) &protocol_version);
    // 配置MQTT服务器地址
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_HOST, (void *) mqtt_host);
    // 配置MQTT服务器端口
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PORT, (void *) &port);
    // 配置设备productKey
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY, (void *) product_key);
    // 配置设备deviceName
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME, (void *) device_name);
    // 配置设备deviceSecret
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET, (void *) device_secret);
    // 配置网络连接的安全凭据, 上面已经创建好了
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *) &cred);
    // 配置MQTT默认消息接收回调函数
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_RECV_HANDLER, (void *) demo_mqtt_default_recv_handler);
    // 配置MQTT事件回调函数
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_EVENT_HANDLER, (void *) demo_mqtt_event_handler);
    // 如果要使用MQTT 5.0的assigned clientId功能, 需要将use_assigned_clientid置为1
    uint8_t use_assigned_clientid = 0;
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_ASSIGNED_CLIENTID, (void *) (&use_assigned_clientid));
    //初始化物模型
    user_dm_init();
    // 创建建连的属性集合,并添加用户属性
    mqtt_properties_t *conn_props = aiot_mqtt_props_init();
    mqtt_property_t user_prop = {
        .id = MQTT_PROP_ID_USER_PROPERTY,
        .value.str_pair.key.len = strlen("demo_key"),
        .value.str_pair.key.value = (uint8_t *) "demo_key",
        .value.str_pair.value.len = strlen("demo_value"),
        .value.str_pair.value.value = (uint8_t *) "demo_value",
    };
    aiot_mqtt_props_add(conn_props, &user_prop);
    // 通过MQTT 5.0的方式与服务器建连
    res = aiot_mqtt_connect_v5(mqtt_handle, NULL, NULL);
    aiot_mqtt_props_deinit(&conn_props);
    if (res < STATE_SUCCESS) {
        //尝试建立连接失败, 销毁MQTT实例, 回收资源
        aiot_dm_deinit(&dm_handle);
        aiot_mqtt_deinit(&mqtt_handle);
        LOG_E("aiot_mqtt_connect failed: -0x%04X\n\r\n", -res);
        LOG_E("please check variables like mqtt_host, produt_key, device_name, device_secret in demo\r\n");
        return -1;
    }

    //创建一个单独的任务用于执行aiot_mqtt_process, 它会自动发送心跳保活, 以及重发QoS1的未应答报文
    g_mqtt_process_task_running = 1;
    xTaskCreate(demo_mqtt_process_task, "aiot_mqtt_process", 1024 * 2, NULL, 3, g_mqtt_process_task);

    // 创建一个单独的任务用于执行aiot_mqtt_recv, 它会循环收取服务器下发的MQTT消息, 并在断线时自动重连
    g_mqtt_recv_task_running = 1;
    xTaskCreate(demo_mqtt_recv_task, "aiot_mqtt_recv", 1024 * 2, NULL, 3, g_mqtt_recv_task);
    //通知MQTT连接成功
    user_state_send_notify(STATE_MQTT_CONNECTED_OK, 0);
    return 0;
}

相关代码已经放在gitee上面m61sdk: 安信可m61模组sdk移植项目 (gitee.com)

遇到问题?

如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23