物模型开发

物模型是阿里云物联网平台为产品定义的数据模型,本文介绍如何通过物模型功能,上报设备属性及事件、设置属性、调用服务等。

前提条件

使用流程

如下功能时序图,以设备的应用程序./demos/data_model_basic_demo.c为例,介绍物模型的基础使用流程。更多API的详细信息,请参考aiot_dm_api.h

image

步骤1: 初始化设备

创建设备句柄,完成设备建连。

static void* demo_device_init(char *product_key, char *device_name, char *device_secret, char *host, uint16_t port)
{
    int32_t res = STATE_SUCCESS;
    /* 创建设备 */
    void *device = aiot_device_create(product_key, device_name);
    if (device == NULL) {
        printf("device create failed\n");
        return NULL;
    }
    /* 设置设备密钥 */
    aiot_device_set_device_secret(device, device_secret);

    /* 连接配置参数初始化 */
    aiot_linkconfig_t* config = aiot_linkconfig_init(protocol);
    /* 设置服务器的host、port */
    aiot_linkconfig_host(config, host, port);

    /* 设置设备连接参数 */
    aiot_device_set_linkconfig(device, config);
    
    /* 设备建连 */
    res = aiot_device_connect(device);
    if (res < STATE_SUCCESS) {
        /* 尝试建立连接失败, 销毁MQTT实例, 回收资源 */
        aiot_linkconfig_deinit(&config);
        aiot_device_delete(&device);
        printf("aiot_device_connect failed: -0x%04X\n\r\n", -res);
        return NULL;
    }

    /* 建连成功返回设备对象 */
    aiot_linkconfig_deinit(&config);
    return device;
}

步骤2: 上报属性

属性上报一般用于上报设备的状态,如下示例表示灯是关闭状态。

 /* 属性上报示例 */
    char *property_params = "{\"LightSwitch\": 0}";
    aiot_device_dm_property_post(device_client, property_params, 1);

步骤3: 设置属性

设备接收到设置属性消息后,会执行回调函数返回设置属性消息,消息类型为:AIOT_DMRECV_PROPERTY_SET,如下示例中设置属性仅做打印处理。

/* 云端->设备:属性设置消息处理示例, 示例只做打印处理  */
static void demo_dm_msg_property_set_callback(void *device, const aiot_dm_msg_t *dm_msg, void *userdata)
{
    printf("demo_dm_msg_property_set_callback params = %.*s\r\n",
        dm_msg->data.property_set.params_len,
        dm_msg->data.property_set.params);

    /* TODO 演示同步回复 */
    char *reply_data = "{}";
    aiot_device_dm_propertyset_reply(device, dm_msg->context, 200, reply_data);

    /* TODO 演示异步回复[不在回调函数中回复], 需要备份消息的上下文用于回复 */
    /*
    void *context = aiot_dm_msg_context_clone(dm_msg->context);
    aiot_device_dm_propertyset_reply(device, dm_msg->context, 200, reply_data);
    aiot_dm_msg_context_free(context);
    */
}

步骤4: 上报事件

事件一般包含需要被外部感知和处理的信息、告警和故障,如下示例中模拟上报一个错误,错误码为-1。

 char *event_id = "Error";
    char *event_params = "{\"ErrorCode\": -1}";
    aiot_device_dm_event_post(device_client, event_id, event_params, 1);

步骤5: 调用服务

服务为设备提供外部调用的指令或方法,如打开电灯可作为一个服务调用实现。如下示例服务调用回调,仅做打印处理。

/* 云端->设备:服务调用消息处理示例, 示例只做打印处理  */
static void demo_dm_msg_service_invoke_callback(void *device, const aiot_dm_msg_t *dm_msg, void *userdata)
{
    printf("demo_dm_msg_service_invoke_callback service_id %s, params = %.*s\r\n",
        dm_msg->data.service_invoke.service_id,
        dm_msg->data.service_invoke.params_len,
        dm_msg->data.service_invoke.params);

    /* TODO 演示同步回复 */
    char *reply_data = "{}";
    aiot_device_dm_service_reply(device, dm_msg->context, dm_msg->data.service_invoke.service_id, 200, reply_data);

    /* TODO 演示异步回复[不在回调函数中回复], 需要备份消息的上下文用于回复 */
    /*
    void *context = aiot_dm_msg_context_clone(dm_msg->context);
    aiot_device_dm_propertyset_reply(device, dm_msg->context, 200, reply_data);
    aiot_dm_msg_context_free(context);
    */
}

步骤6: 反初始化设备

 /* 断开设备连接,并回收设备资源 */
    demo_device_deinit(device_client);