本文说明如何使用移植在zephyr上使用Link Kit SDK开发物联网应用
在移植一文中说明了如何将阿里云的link kit sdk移植到zephyr,这里我们更进一步使用link kit sdk在zephyr开发一个应用,用于发布本地的温度和湿度到阿里云,并订阅阿里云上收到的温度和湿度到本地。
云端
云端主要是增加功能定义,在阿里云物联网平台上点击”产品->功能定义”,在自定义功能中”添加功能”,如下图
点击添加功能后会弹出功能框,如下图
这里我添加了湿度和温度两个,类型,取值,步长都根据实际device来设置,标识符唯一标示功能的字符串,在device端会用到,如下图
设备端
设备端使用Zephyr的驱动获取温湿度,再通过阿里云SDK将温湿度送到云端
主程序
1 | void main(void) |
发布
注意其payload,已json数据的形式将温度和湿度通过IOT_MQTT_Publish_Simple发送到云端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
47int example_publish(void *handle)
{
int res = 0;
//Topic模板
const char *fmt = "/sys/%s/%s/thing/event/property/post";
char *topic = NULL;
int topic_len = 0;
//Payload模板
char *payload = "{\
\"id\": %d,\
\"params\": {\
\"TargetTemperature\": %d,\
\"Humidity\": %d\
},\
\"method\": \"thing.event.property.post\"}";
topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
topic = HAL_Malloc(topic_len);
if (topic == NULL) {
EXAMPLE_TRACE("memory not enough");
return -1;
}
memset(topic, 0, topic_len);
//准备topic数据
HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
memset(acPayload, 0, 128);
//准备payload数据,温度,湿度
HAL_Snprintf(acPayload, 128, payload, idnumber++, temp.val1, humidity.val1);
EXAMPLE_TRACE("Topic %s\n", topic);
EXAMPLE_TRACE("Payload %s\n", acPayload);
//
res = IOT_MQTT_Publish_Simple(0, topic, IOTX_MQTT_QOS0, acPayload, strlen(acPayload));
if (res < 0) {
EXAMPLE_TRACE("publish failed, res = %d", res);
HAL_Free(topic);
return -1;
}
HAL_Free(topic);
return 0;
}
topic
使用云端已定义好的topic,如图
对照加入topic模板,其中字符串分别对应的是product key和device name1
2const char *fmt = "/sys/%s/%s/thing/event/property/post";
HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
Payload
这里将报温度和湿度已Json格式上报
模板如下:1
2
3
4
5
6
7char *payload = "{\
\"id\": %d,\
\"params\": {\
\"TargetTemperature\": %d,\
\"Humidity\": %d\
},\
\"method\": \"thing.event.property.post\"}";
对应的value可根据情况定义,代码中是顺序增加的.
温度和湿度的key从前面提到的在云端的“标识符”来,对应的value就是想要上报的温度和湿度
method将topic的device name的string对应转换而来,thing/event/property/post -> thing.event.property.post 这点必须匹配,否则上报数据会出错
实例:1
"id": 1,"params": {"TargetTemperature": 29,"Humidity": 29},"method": "thing.event.property.post"}
云端显示的示例在概览一文有贴出,这里贴出一下device端的log1
2
3
4
5
6
7
8
9
10
11
12
13
14uart:~$ publish
example_publish|116 :: Topic /sys/a10Bd3A14DDC/4Z3Oeud7Sh5cod49oo2U/thing/event/property/post
example_publish|117 :: Payload {"id": 1,"params": {"TargetTemperature": 29,"Humidity": 29},"method": "thing.event.property.post"}
> {
> "id": 1,
> "params": {
> "TargetTemperature": 29,
> "Humidity": 29
> },
> "method": "thing.event.property.post"
> }
订阅
device订阅也很简单,下面代码示例订阅user/get topic内容,当收到云端发布的信息后,将数据打印出来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
44void example_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
iotx_mqtt_topic_info_t *topic_info = (iotx_mqtt_topic_info_pt) msg->msg;
switch (msg->event_type) {
case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
/* print topic name and topic message */
EXAMPLE_TRACE("Message Arrived:");
EXAMPLE_TRACE("Topic : %.*s", topic_info->topic_len, topic_info->ptopic);
EXAMPLE_TRACE("Payload: %.*s", topic_info->payload_len, topic_info->payload);
EXAMPLE_TRACE("\n");
break;
default:
break;
}
}
int example_subscribe(void *handle)
{
int res = -1;
const char *fmt = "/%s/%s/user/get";
char *topic = NULL;
int topic_len = 0;
topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
topic = HAL_Malloc(topic_len);
if (topic == NULL) {
EXAMPLE_TRACE("memory not enough");
return -1;
}
memset(topic, 0, topic_len);
HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
//订阅信息
res = IOT_MQTT_Subscribe(handle, topic, IOTX_MQTT_QOS0, example_message_arrive, NULL);
if (res < 0) {
EXAMPLE_TRACE("subscribe failed");
HAL_Free(topic);
return -1;
}
HAL_Free(topic);
return 0;
}
topic
使用云端已定义好的topic,如图
和上面代码自行对应不再详述
云端发布
点击Topic的发布消息,在弹出的对话框中发布数据,如图
发布成功后device端可以收到数据,log如下1
2
3
4
5example_event_handle|132 :: msg->event_type : 12
example_message_arrive|052 :: Message Arrived:
example_message_arrive|053 :: Topic : /a10Bd3AmDDC/4Z0Oeud7Sh4cod49oo2U/user/get
example_message_arrive|054 :: Payload: Hello half coder!!
example_message_arrive|055 ::
其它
测试过程中有zephyr网络用一会就不通的情况,原因是NET_PKG和BUF给小了,增大即可1
2
3
4CONFIG_NET_PKT_RX_COUNT=34
CONFIG_NET_PKT_TX_COUNT=34
CONFIG_NET_BUF_RX_COUNT=34
CONFIG_NET_BUF_TX_COUNT=34
后记
终于将zephyr接入阿里云收尾,主要是将云端和device串起来并了解zephyr上使用阿里云物联网SDK, 更深入的内容是MQTT/阿里云物联网SDK的使用相关,就不再深入研究了。