本系列主要目的在于记录腾讯云物联网设备端的学习笔记,并且对设备端SDK进行补充说明。
简介
数据模板相关概念,请参见数据模板
数据模板功能实现,请参见数据模板功能及实现
以下介绍如何基于数据模板进行应用开发,主要包括数据模板代码化、下行数据处理、上行数据上报。
源码请参见:
https://github.com/xyfancy/iot-hub-device-c-sdk/tree/master/app/data_template
数据模板代码化
核心思想:将数据模板定义转换成相应的C代码数据类型,比如整数型->int,提供通用的接口根据索引访问(该实现处于beta版本,后续采用脚本自动化生成)。
源码:data_template_config.c 和 data_template_config.h
以灯开关属性为例:
1.初始化
属性包括:
- type:对应数据模板类型
- key:对应该属性的关键字
- value:值的存储空间
- need_report:是否需要上报,当值发生改变时,需要上报平台用作同步(特别地:如果只是下行属性,且不用平台保存状态,可以不用上报)
struct DataTemplateProperty {
DataTemplatePropertyType type;
const char* key;
DataTemplatePropertyValue value;
int need_report;
};
根据控制台上数据模板的定义,初始化开关属性:
- 类型:布尔型
- 关键字:power_switch
- 值:可用C语言中的int存储,其中值使用了联合类型,用户需要根据数据模板类型来选择成员。
- 是否上报:因为开关离线状态下可有人为修改,所以初始化时需要上报)
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER_SWITCH].value.value_bool = 0;
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER_SWITCH].key = "power_switch";
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER_SWITCH].type = DATA_TEMPLATE_TYPE_BOOL;
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER_SWITCH].need_report = 1;
2.接口调用
通过将数据模板建立索引,通过索引进行访问相应的数据模板
代码语言:javascript复制typedef enum {
USR_PROPERTY_INDEX_POWER_SWITCH = 0, // 开关索引
USR_PROPERTY_INDEX_COLOR,
USR_PROPERTY_INDEX_BRIGHTNESS,
USR_PROPERTY_INDEX_NAME,
USR_PROPERTY_INDEX_POSITION,
USR_PROPERTY_INDEX_POWER,
} UsrPropertyIndex;
代码语言:javascript复制//初始化
void usr_data_template_init(void);
//获取非结构体类型的数据模板值
DataTemplatePropertyValue usr_data_template_property_value_get(UsrPropertyIndex index);
//设置非结构体类型的数据模板值
void usr_data_template_property_value_set(UsrPropertyIndex index, DataTemplatePropertyValue value);
//获取结构体类型的数据模板值
DataTemplatePropertyValue usr_data_template_property_struct_value_get(UsrPropertyIndex struct_index,
int property_index);
//设置结构体类型的数据模板值
void usr_data_template_property_struct_value_set(UsrPropertyIndex struct_index, int property_index,
DataTemplatePropertyValue value);
//获取行为中输入参数的数据模板值
DataTemplatePropertyValue usr_data_template_action_input_value_get(UsrActionIndex index, int property_index);
代码语言:javascript复制// 通过解析control或者get_status中control消息中的params设置相应的属性
void usr_data_template_property_parse(UtilsJsonValue params);
// 上报所有需要上报的属性,need_report为1
int usr_data_template_property_report(void* client, char* buf, int buf_len);
// 上报事件,此处用户自行构造json,灵活度更高
void usr_data_template_event_post(void* client, char* buf, int buf_len, UsrEventIndex id, const char* params);
// 通过解析action消息中的输入参数设置相应的属性
int usr_data_template_action_parse(UtilsJsonValue action_id, UtilsJsonValue params, UsrActionIndex* index);
// 行为的回复
int usr_data_template_action_reply(void* client, char* buf, int buf_len, UsrActionIndex index,
UtilsJsonValue client_token, int code, const char* response);
下行数据处理
源码:data_template_app.c
下行数据主要包括:
- control消息:回调中设置属性值,然后读取属性值进行处理
- method_control_callback->usr_data_template_property_parse->usr_data_template_property_value_get
- action消息:回调中设置输入参数属性值,然后读取属性值进行处理
- method_action_callback->usr_data_template_action_parse->usr_data_template_action_input_value_get
- get_status消息:回调中设置control消息的属性值,然后读取属性值进行处理
- method_get_status_reply_callback->usr_data_template_property_parse->usr_data_template_property_value_get
- 各类消息的回复:
- 如果需要实现QOS1质量,请在应用层建立队列实现(这里取决于业务,不同业务要求对于重发的要求以及超时的时间均不一致,后续根据业务经验总结出典型的示例)。
- 如果是QOS0质量,可直接忽略所有的回复(大部分数据采集类的消息均可如此处理)。
上行数据上报
源码:data_template_app.c
上线行数据主要包括:
- report消息:设置属性值(need_reoprt置为1),然后调用接口上报所有need_report为1 的属性
- usr_data_template_property_value_set->usr_data_template_property_report
- control_reply消息:回调中调用接口直接回复,实际不回复也行,取决于业务
- method_control_callback->IOT_DataTemplate_PropertyControlReply
- action_reply消息:调用中根据结果进行回复,因为云API有超时限制,所以回复必须立即,如果完成不了行为,请采用属性上报的方式回复。
- method_action_callback->usr_data_template_action_reply
- event上报:调用接口,自行改造json上报,sdk中提供了示例。这样更灵活且简单
- usr_data_template_event_post
注意事项
本文提供的方法针对以往的业务进行总结设计,有以下限制,请根据业务进行修改:
- 默认所有的属性通过usr_data_template_property_value_set设置后均会置need_report为1,并在调用usr_data_template_property_report后上报。如果不需要上报的属性,可自行根据属性索引进行过滤。
- usr_data_template_property_parse会解析json中所有的属性并设置,如果需要多个属性共同生效的业务,请将这些属性整合到结构体或者字符串类型中,或者修改该接口的实现,针对索引进行判断。
- 所有回复均不处理,针对某些特殊的场景(弱网),应用层实现QOS1,目前接触的项目需求较少。