# 设备端数据上报

# 物模型数据上报

  • 修改 thing_model_demo.c 的三元组信息为设备对应的三元组信息
char *product_key = "KS78JR0J";
char *device_name = "testdemo";
char *secret = "5b28b44337b53ef5261d6335af5c8075";
1
2
3
  • 修改 host 和 port
char *host = "8.136.220.253";
int port = 1883;
1
2
  • 设置重连间隔和重连次数
int reconnect_interval = 10;
int reconnect_time = 3;
1
2
  • 根据已定义好的物模型所对应 TSL 修改 model_id
char *model_id = "test_model_id";
1
  • 根据获取的物模型的 TSL 更改下列参数。

    属性参数修改,根据 web 端生成的物模型描述,如下是属性相关参数,以及相关设置。

"properties": [
    {
      "identifier": "property_a1",
      "is_required": false,
      "data_type": {
        "type": "int"
      }
    },
    {
      "identifier": "property_a2",
      "is_required": false,
      "data_type": {
        "type": "double"
      }
    },
    {
      "identifier": "property_a3",
      "is_required": false,
      "data_type": {
        "type": "text"
      }
    },
    {
      "identifier": "property_b",
      "is_required": false,
      "data_type": {
        "type": "struct",
        "specs": [
          {
            "identifier": "aaaa",
            "data_type": {
              "type": "int"
            }
          },
          {
            "identifier": "bbbb",
            "data_type": {
              "type": "int"
            }
          },
          {
            "identifier": "cccc",
            "data_type": {
              "type": "double"
            }
          }
        ]
      }
    },
    {
      "identifier": "property_c",
      "is_required": false,
      "data_type": {
        "type": "array",
        "specs": {
          "size": 10,
          "item": {
            "type": "int"
          }
        }
      }
    },
    {
      "identifier": "property_d",
      "is_required": false,
      "data_type": {
        "type": "array",
        "specs": {
          "size": 10,
          "item": {
            "type": "double"
          }
        }
      }
    },
    {
      "identifier": "property_e",
      "is_required": false,
      "data_type": {
        "type": "array",
        "specs": {
          "size": 10,
          "item": {
            "type": "text"
          }
        }
      }
    },
    {
      "identifier": "property_f",
      "is_required": false,
      "data_type": {
        "type": "array",
        "specs": {
          "size": 10,
          "item": {
            "type": "struct",
            "specs": [
              {
                "identifier": "asdf",
                "data_type": {
                  "type": "int"
                }
              },
              {
                "identifier": "hjkl",
                "data_type": {
                  "type": "int"
                }
              }
            ]
          }
        }
      }
    }
  ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// 原生类型参数设置
int    val_i1     = 0;
int    val_i2     = 0;
char   val_s3[16] = "text";
double val_d4     = 23.7;
double val_d5     = 23.7;
char   val_s6[16] = "1629344092";

// 结构体类型参数设置
emqc_tm_object val_struct[] = {
    { .type = EMQC_TM_INT, "aaaa", .val_i = 0 },
    { .type = EMQC_TM_INT, "bbbb", .val_i = 0 },
    { .type = EMQC_TM_DOUBLE, "cccc", .val_d = 0.0 },
    { .type = EMQC_TM_TERMINATOR, "", .val_o = NULL }
};

// 数组类型参数设置
int *val_arr_int[] = {&val_i1, &val_i2, NULL};
double *val_arr_dou[] = {&val_d4, &val_d5, NULL};
char *val_arr_str[] = {val_s3, val_s6, NULL};

// 结构体数组类型设置
emqc_tm_object val_struct1[] = {
    { EMQC_TM_INT, "asdf", .val_i = 0 },
    { EMQC_TM_INT, "hjkl", .val_i = 0 },
    // 这里是作为结束符必须的
    { EMQC_TM_TERMINATOR, "", .val_o = NULL } 
};

emqc_tm_object val_struct2[] = {
    { EMQC_TM_INT, "asdf", .val_i = 0 },
    { EMQC_TM_INT, "hjkl", .val_i = 0 },
    // 这里是作为结束符必须的
    { EMQC_TM_TERMINATOR, "", .val_o = NULL } 
};

emqc_tm_object *val_arr_struct[] = {
    val_struct1,
    val_struct2,
    NULL // 这里是作为结束符必须的
};

// 最终要上报的数据全部配置到这里
emqc_tm_object property_array[] = {
    { .type = EMQC_TM_INT,  .key = "property_a1", .val_i = 10 },
    { .type = EMQC_TM_DOUBLE,  .key = "property_a2", .val_d = 10.10 },
    { .type = EMQC_TM_STR,  .key = "property_a3", .val_s = val_s6 },
    { .type = EMQC_TM_STRUCT,  .key = "property_b", .val_o = &val_struct },
    { .type = EMQC_TM_ARR_INT,  .key = "property_c", .val_o = &val_arr_int },
    { .type = EMQC_TM_ARR_DOUBLE,  .key = "property_d", .val_o = &val_arr_dou },
    { .type = EMQC_TM_ARR_STR,  .key = "property_e", .val_o = &val_arr_str },
    { .type = EMQC_TM_ARR_STRUCT,  .key = "property_f", .val_o = &val_arr_struct },
    // 这里是作为结束符必须的
    { .type = EMQC_TM_TERMINATOR, .key = "", .val_o = NULL },
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

​ 属性上报函数,响应函数以及属性设置回调。

// 属性上报
void property_post(emqc_tm *tm)
{
    char sfx[] = "property/post";
    char mtd[] = "thing.property.post";
    char topic[EMQC_TM_TOPIC_LEN];

    json_object *jso = emqc_tm_new_payload(mtd, NULL);
    int          i   = 0;
    do {
        if (property_array[i].type == EMQC_TM_TERMINATOR) {
            break;
        }
        emqc_tm_add_post_param(jso, &property_array[i], model_id);
    } while (++i);

    snprintf(topic, EMQC_TM_TOPIC_LEN, TM_FMT, product_key, device_name, sfx);
    log_info("#PUB: %s", topic);
    log_info("#PAYLOAD: %s", json_object_to_json_string(jso));
    emqc_tm_pub(tm, topic, json_object_to_json_string(jso));
    json_object_put(jso);
    return;
}

// 属性响应回调
void *property_post_reply_cb(void *payload)
{
    emqc_tm_trans_object *obj = (emqc_tm_trans_object*) payload;
    if (obj) {
        switch (obj->type) {
            // 符合物模型协议的数据,从这里获取
            case TM_REP:;
                tm_reply *tr = obj->rep;
                log_info("#RECV: id: %s, code: %d, data: %s", tr->id, tr->code, tr->data);
                break;
            // 自定义数据,从这里获取
            case TM_RAW:
                log_info("#RECV: raw_data: %s", obj->raw);
                break;
            default:
                log_err("Error trans type.");
        }
    }
    return NULL;
}

// 属性设置回调
void *property_set_cb(void *payload)
{
    emqc_tm_trans_object *obj = (emqc_tm_trans_object*) payload;
    char *ret = NULL;
    if (obj) {
        switch (obj->type) {
            case TM_REQ:;// 符合物模型协议的数据,从这里获取
                tm_request *tr = obj->req;
                log_info("#RECV: id: %s, version: %s, method: %s, params: %s", tr->id,
                         tr->version, tr->method, tr->params);
                // 设置操作
                json_object *jso_tmp = json_tokener_parse(tr->params);
                emqc_tm_property_set(jso_tmp, property_array, model_id);

                json_object *jso      = json_object_new_object();
                json_object *jso_data = json_object_new_object();
                json_object_object_add(jso, "id", json_object_new_string(tr->id));
                json_object_object_add(jso, "code", json_object_new_int(0));
                json_object_object_add(jso, "data", jso_data);
                ret = zstrdup(json_object_to_json_string(jso));
                json_object_put(jso);
                break;
            case TM_RAW:// 自定义数据,从这里获取
                log_info("#RECV: raw_data: %s", obj->raw);
                break;
            default:
                log_err("Error trans type.");
        }
    }

    return (void *) ret;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

​ 事件参数修改,根据 web 端生成的物模型描述,如下是事件相关参数,以及相关设置。

 "events": [
    {
      "identifier": "events",
      "is_required": false,
      "event_type": "EVENT_TYPE_INFO",
      "output_data": [
        {
          "identifier": "param01",
          "data_type": {
            "type": "array",
            "specs": {
              "size": 10,
              "item": {
                "type": "text"
              }
            }
          }
        }
      ]
    }
  ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
char val_param01_s1[] = "param011";
char val_param01_s2[] = "param012";
char val_param01_s3[] = "param013";
char val_param01_s4[] = "param014";
char val_param01_s5[] = "param015";
char val_param01_s6[] = "param016";
char val_param01_s7[] = "param017";
char val_param01_s8[] = "param018";
char val_param01_s9[] = "param019";

char *param01[] = {
	val_param01_s1,
	val_param01_s2,
	val_param01_s3,
	val_param01_s4,
	val_param01_s5,
	val_param01_s6,
	val_param01_s7,
	val_param01_s8,
	val_param01_s9,
	NULL
 };

char *event_idents[] = {
	"events", // 如果有多个 identifer 顺序添加,最后一个元素一定是 NULL。
	NULL,
};
emqc_tm_object event_array[] = {
	{ .type = EMQC_TM_ARR_STR, .key = "param01", .val_o = &param01 },
	{ .type = EMQC_TM_TERMINATOR, .key = "", .val_o = NULL },
 };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

​ 服务参数修改,根据 web 端生成的物模型描述,如下是服务相关参数,以及相关设置。

 "actions": [
    {
      "identifier": "service01",
      "is_required": false,
      "input_data_param": [
        {
          "identifier": "input_param",
          "data_type": {
            "type": "int"
          }
        }
      ],
      "output_data_param": [
        {
          "identifier": "output_param",
          "data_type": {
            "type": "int"
          }
        }
      ]
    }
  ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18