由 wxlinus 贡献,Ai-Thinker 进行整理
【Clion开发】【二】阿里云物联网平台使用之M61开发板连接阿里云平台
经过上面的相关内容我们已经可以连接到阿里云物联网平台了,现在我们就来学习一下如何使用阿里云物联网平台的物模型功能 物模型是阿里云物联网平台为产品定义的数据模型,用于描述产品的功能。

物模型详细的内容添加与新建可以参考官方文档:定义物模型属性、事件和服务_物联网平台(IoT)-阿里云帮助中心 (aliyun.com) 我们下边就讲讲如何使用物模型来点m61开发板上面的灯 
灯的定义
/*
* RGB灯引脚定义
*/
#define LED3_R 12
#define LED3_G 14
#define LED3_B 15操作步骤
物模型属性上报:云端会根据上报数据改变设备状态(示例中暂时注释,因为上报频率高会打印太多日志,不利于调试)。
上报的数据会对应到云端的对应物模型属性,详细参考官方文档。例如 LightSwitch 就是把对应标识的物模型数据变为 0:{"LightSwitch": 0}。

云端通过 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);
}
在云端打开调试页面设置一下属性:
可以看到设备端接收到了对应消息,开发板上的灯也亮了:

物模型还有很多功能,比如采集温湿度传感器数据上报到云端,方法都是类似的,只要新建对应的物模型即可。基于物模型还能做数据流转、数据保存、云产品流转、Web 可视化等内容。
设备端物模型相关的函数回调由以下函数实现(本次涉及的是属性设置函数:收到数据后解析,判断对应状态,然后开灯与关灯)。物模型相关 API 作为组件集成到 linksdk 中:
初始化相关代码主要是 MQTT 初始化中以 dm 开头的一些函数,完整代码见下方。
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


