
# Demo3
Demo代码中具体实现的是模拟电机设备上报数据，SDK获取上报数据做进一步分析处理。
如果遇到状态为error，则调用事先在产品模型定义好的设备命令。对于未指定MOTOR_PRODUCT_ID的产品上报的数据将继续上报给云端。
![](https://support.huaweicloud.com/devg-iotedge/public_sys-resources/note_3.0-zh-cn.png)
该Demo的应用可参考[集成ModuleSDK进行数据处理](https://support.huaweicloud.com/devg-iotedge/iotedge_devg_0069.html)。
```
#include "edge.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/*
 * 描述：收到设备上报数据的回调处理，样例代码在马达设备状态错误时对马达进行重启
 * 参数：
 *  body：收到的消息，body格式
 *  {
 *      "device_id":"device_id",
 *      "product_id":"product_id",
 *      "services":[{
 *          "service_id":"service_id",
 *          "properties":{},
 *          "event_time":"12211"
 *      }]
 *  }
 *  body_len: 长度
 * */
EDGE_RETCODE on_message_received_cb(const char* body, unsigned int body_len)
{
    // 设置发送设备数据的消息总线输出点，取值需在创建应用版本的outputs参数中定义
    char* output_name = "output";
    printf("receive message: %s\n", body);
    printf("start send message to output topic: %s\n", output_name);
    char* product_id  = "";  // 从body中获取
    // 设置电机设备产品ID
    char* MOTOR_PRODUCT_ID = "product_123";
    if (strcmp(product_id, MOTOR_PRODUCT_ID) == 0)
    {
        //马达设备状态错误时对马达进行重启
        char* error = "error";
        char* is_error = strstr(body, error);
        // 设置默认超时时间（单位毫秒）
        unsigned int timeout = 5000;
        ST_COMMAND command = {0};
        command.object_device_id = "device_id_001";
        command.service_id = "power";
        command.command_name = "restart";
        command.paras = "my test paras";
        // 调用设备命令重启
        if (is_error != NULL)
        {
            ST_COMMAND_RSP* cmd_response = NULL;
            int ret = edge_call_device_command(&command, timeout, &cmd_response);
            if (ret == EDGE_SUCCESS && cmd_response) {
                printf("Command success! result_code: %d, response_name: %s\n", cmd_response->result_code,cmd_response->response_name);
                if (cmd_response->paras) {
                    // 直接打印原始 JSON 字符串
                    printf("Raw JSON Paras: %s\n", cmd_response->paras);
                    /*
                    // 按需解析为 cJSON 对象
                    cJSON* paras_json = cJSON_Parse(cmd_response->paras);
                    if (paras_json) {
                        cJSON* result = cJSON_GetObjectItem(paras_json, "result");
                        if (cJSON_IsString(result)) {
                            printf("Result from paras: %s\n", result->valuestring);
                        }
                        cJSON_Delete(paras_json);
                    }*/
                }
                edge_free_command_rsp(cmd_response); // 记得使用后释放，否则内存泄漏
            }
        }
    }
    else {
        //其他设备数据发送到消息总线
        edge_send_bus_message(output_name, body, body_len);
    }
    printf("process ended.\n");
    return EDGE_SUCCESS;
}
/*
 * 描述：设置总线消息回调，用于对设备上报的数据进行处理
 * 参数：
 *  input_name：消息总线输入点
 * */
EDGE_RETCODE set_bus_message_cb(const char* input_name)
{
    edge_set_bus_message_cb(input_name, on_message_received_cb);
    printf("set bus message callback with input name: %s\n", input_name);
    return EDGE_SUCCESS;
}
/*
 * 监控APP，检视设备上报的数据，并对设备进行相应的控制
 */
void monitor_app()
{
    // 禁用缓冲区
    setvbuf(stdout, NULL, _IONBF, 0);
    printf("start monitor app\n");
    //初始化sdk，工作路径设置（工作路径下需要含有 /conf  目录（该目录下包含证书等信息））
    edge_init("../code/api_test/workdir");
    ST_MODULE_CBS module_cbs = {0};
    ST_DEVICE_CBS device_cbs = {0};
    // 设置回调函数
    edge_set_callbacks(&module_cbs, &device_cbs);
    printf("SDK start running!\n");
    sleep(1);
    edge_login();
    sleep(1);
    // 接受设备数据的消息总线输入点，取值需在创建应用版本的inputs参数中定义
    char* input_name = "input";
    set_bus_message_cb(input_name);
    // 这里是为了使应用能够长时间运行
    while(1)
    {
        sleep(1000);
    }
    edge_logout();
    sleep(1000);
    edge_destroy();
}
int main()
{
    // 监控app demo
    monitor_app();
    return 0;
}
```
