- [数据模板业务逻辑开发发](#%E6%95%B0%E6%8D%AE%E6%A8%A1%E6%9D%BF%E4%B8%9A%E5%8A%A1%E9%80%BB%E8%BE%91%E5%BC%80%E5%8F%91%E5%8F%91) - [下行业务逻辑实现](#%E4%B8%8B%E8%A1%8C%E4%B8%9A%E5%8A%A1%E9%80%BB%E8%BE%91%E5%AE%9E%E7%8E%B0) - [上行业务逻辑实现现](#%E4%B8%8A%E8%A1%8C%E4%B8%9A%E5%8A%A1%E9%80%BB%E8%BE%91%E5%AE%9E%E7%8E%B0%E7%8E%B0) ## 数据模板业务逻辑开发发 数据模板示例`data_template_app.c`已实现数据、事件收发及响应的通用处理框架。可以基于此示例开发业务逻辑, 上下行业务逻辑处理的入口函数分别为 `_usr_init`、`_method_control_callback` 、`_cycle_report`、`_method_action_callback`。 - 属性 属性即对设备能力的描述,譬如智能灯,通过 `开关`、`颜色`、`亮度`三个属性实现对智能灯的能力描述,通过对属性的修改即可实现对设备的控制。 - 事件 设备发生特定情况,譬如灯的开关状态发生了变化,上报事件。应用侧收到事件后按预设逻辑推送事件。 - 行为 控制设备执行特定的行为,并将执行的结果返回。行为与属性的区别,概念上行为是数据和方法的组合,行为有执行结果的返回。属性只有数据,修改属性后设备侧是否执行成功很难在属性本身体现。 ### 下行业务逻辑实现 - 服务端下行的数据,SDK已按数据模板协议完成了 json 数据的解析。 - 用户根据数据模板数据进行相应的业务逻辑处理,以下提供基于智能灯的示例,用户可以根据自己的物模型进行修改 ```c static void _handle_property_callback(void *client, int is_get_status) { for (UsrPropertyIndex i = USR_PROPERTY_INDEX_POWER_SWITCH; i <= USR_PROPERTY_INDEX_POWER; i++) { if (usr_data_template_property_status_get(i)) { // 如果状态改变,说明收到了相应的属性 DataTemplatePropertyValue value; switch (i) { case USR_PROPERTY_INDEX_POWER_SWITCH: case USR_PROPERTY_INDEX_COLOR: case USR_PROPERTY_INDEX_BRIGHTNESS: // read only, just for example case USR_PROPERTY_INDEX_POWER: // read only, just for example value = usr_data_template_property_value_get(i); // 获取相应的属性值 Log_d("recv %s:%d", usr_data_template_property_key_get(i), value.value_int); break; case USR_PROPERTY_INDEX_NAME: // read only, just for example value = usr_data_template_property_value_get(i); Log_d("recv %s:%s", usr_data_template_property_key_get(i), value.value_string); break; case USR_PROPERTY_INDEX_POSITION: // read only, just for example for (UsrPropertyPositionIndex j = USR_PROPERTY_POSITION_INDEX_LONGITUDE; j <= USR_PROPERTY_POSITION_INDEX_LATITUDE; j++) { value = usr_data_template_property_struct_value_get(i, j); Log_d("recv %s:%d", usr_data_template_property_struct_key_get(i, j), value.value_int); } break; default: break; } usr_data_template_property_status_reset(i); //处理完需要重置属性状态 } } } ``` ```c static void _method_action_callback(UtilsJsonValue client_token, UtilsJsonValue action_id, UtilsJsonValue params, void *usr_data) { UsrActionIndex index; int rc; DataTemplatePropertyValue value_time, value_color, value_total_time; char buf[256]; Log_i("recv msg[%.*s]: action_id=%.*s|params=%.*s", client_token.value_len, client_token.value, action_id.value_len, action_id.value, params.value_len, params.value); // 数据模板行为 json 格式解析 rc = usr_data_template_action_parse(action_id, params, &index); if (rc) { return; } // 修改和添加下行行为数据的具体业务逻辑 switch (index) { case USR_ACTION_INDEX_LIGHT_BLINK: value_time = usr_data_template_action_input_value_get(USR_ACTION_INDEX_LIGHT_BLINK, USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TIME); value_color = usr_data_template_action_input_value_get(USR_ACTION_INDEX_LIGHT_BLINK, USR_ACTION_LIGHT_BLINK_INPUT_INDEX_COLOR); value_total_time = usr_data_template_action_input_value_get(USR_ACTION_INDEX_LIGHT_BLINK, USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TOTAL_TIME); Log_i("light[%d] blink %d every %d s ", value_color.value_enum, value_time.value_int, value_total_time.value_int); // 下行行为数据处理结果的回复 usr_data_template_action_reply(usr_data, buf, sizeof(buf), index, client_token, 0, "{\"err_code\":0}"); break; default: break; } } ``` ### 上行业务逻辑实现现 - SDK提供了属性、事件、行为的上行接口,用户可以按数据模板协议自行构造数据,然后调用接口上报相应数据。 1. 属性上报接口`usr_data_template_property_report` 2. 事件上报接口`usr_data_template_event_post` 3. 行为回复接口`usr_data_template_action_reply` - 数据模板示例 data_template_app.c 已提供了属性、事件、行为数据构造和上报的框架。 1.对于属性上报,调用修改对应属性参数的接口 `usr_data_template_property_value_set`,然后调用属性上报接口`usr_data_template_property_report`会将需要上报的属性信息上报。 ```c // 参考 _usr_init 函数,设备在业务运行过程中修改属性后需要调用以下对应函数修改对应的属性 // usr_data_template_property_report(client, buf, sizeof(buf)); 函数进行属性数据的上报 static void _usr_init(void) { usr_data_template_init(); DataTemplatePropertyValue value; value.value_int = 0; usr_data_template_property_value_set(USR_PROPERTY_INDEX_POWER_SWITCH, value); value.value_enum = 0; usr_data_template_property_value_set(USR_PROPERTY_INDEX_COLOR, value); value.value_int = 10; usr_data_template_property_value_set(USR_PROPERTY_INDEX_BRIGHTNESS, value); value.value_string = "light"; usr_data_template_property_value_set(USR_PROPERTY_INDEX_NAME, value); value.value_int = 30; usr_data_template_property_struct_value_set(USR_PROPERTY_INDEX_POSITION, USR_PROPERTY_POSITION_INDEX_LONGITUDE, value); value.value_int = 30; usr_data_template_property_struct_value_set(USR_PROPERTY_INDEX_POSITION, USR_PROPERTY_POSITION_INDEX_LATITUDE, value); value.value_string = "high"; usr_data_template_property_value_set(USR_PROPERTY_INDEX_POWER, value); } ``` 2.对于事件,在事件产生的地方,构造事件的 json 串并调用事件上报接口`usr_data_template_event_post`上报。 ```c static void _cycle_report(void *client) { char buf[256]; static QcloudIotTimer sg_cycle_report_timer; if (IOT_Timer_Expired(&sg_cycle_report_timer)) { // 添加和修改业务需要上报的事件数据 usr_data_template_event_post(client, buf, sizeof(buf), USR_EVENT_INDEX_STATUS_REPORT, "{\"status\":0,\"message\":\"ok\"}"); IOT_Timer_Countdown(&sg_cycle_report_timer, 60); } } ``` 3.对于行为,在行为的回调 `_method_action_callback` 中,添加业务逻辑执行对应的行为,根据行为执行结果,构造行为的输出参数,调用行为回复接口`usr_data_template_action_reply`上报行为执行结果。 ```c usr_data_template_action_reply(usr_data, buf, sizeof(buf), index, client_token, 0, "{\"err_code\":0}"); ```