OneNET-中国移动物联网开放平台是由中国移动打造的PaaS物联网开放平台。平台能够帮助开发者轻松实现设备接入与设备连接,提供综合性的物联网解决方案,实现物联网设备的数据获取,数据存储,数据展现。本文就介绍如何将传统的设备连接到OneNET。 采用MQTT+JSON格式对接OneNET平台上传温度度的数据,当然我们也可以在平台下发消息来控制设备。
1.操作和实战
注册OneNET:https://open.iot.10086.cn/,注册OneNET账号。注册过程比较简单这里就不再累述。登录之后。打开产品服务 MQTT物联网套件点击立刻使用,如下图所示:
进入MQTT物联网套件,在该页面点击添加产品,如下图所示:
从上图中,技术参数根据自己的硬件选择,如果我们的联网硬件为无线产品,则选择wifi;如果我们的联网硬件为有线产品,则选择移动蜂窝网络。协议为MQTTS,操作系统为无,而网络运营商可以全选,最后点击完成就可以创建产品,如下图所示:
点击上图的产品,进入相关界面,然后点击设备列表创建设备,如下图所示:
添加完成之后,我们得到一个设备,,如下图所示:
点击上图中的数据流,这些数据流是由用户添加的,例如显示温湿度等等,如下图所示:
最后我们得到三元组内容,如下源码所示:
#define CLIENTID "MQTT"
#define USERNAME "366007"
#define PASSWORD "version=2018-10-31&res=products%2F366007%2Fdevices%2FMQTT&et=1672735919&method=md5&sign=qI0pgDJnICGoPdhNi%2BHtfg%3D%3D"
上述的参数是由OneNET来提供,MQTT是刚刚我们创建的设备名称,“366007”是刚刚我们创建的产品ID,而密钥是从产品概述获取,如下图所示:
上述是OneNET平台构建MQTT服务器完成,下面我们讲解代码部分。
2. MQTT源码包和cjSON源码包下载
MQTT官方网址(http://mqtt.org/)下载MQTT代码包; cjSON官方网址(https://sourceforge.net/projects/cjson/)下载cjSON代码包; 然后把这些源码移植到我们工程当中,移植步骤如下所示: (1)添加一下源码到工程当中
(2)在工程添加一下分组:
(3)添加这些源码头文件路径:
3. 连接
#define CLIENTID "MQTT"
#define USERNAME "366007"
#define PASSWORD "version=2018-10-31&res=products%2F366007%2Fdevices%2FMQTT&et=1672735919&method=md5&sign=qI0pgDJnICGoPdhNi%2BHtfg%3D%3D"
#define HOST_NAME "open.iot.10086.cn"
#define HOST_PORT 1883
#define DEVICE_SUBSCRIBE "$sys/"USERNAME"/"CLIENTID"/dp/post/json/+"
#define DEVICE_PUBLISH "$sys/"USERNAME"/"CLIENTID"/dp/post/json"
订阅和发布的写法根据OneNET的要求而定义。
(2) 在onenet.c文件定义四个函数,分别连接、获取、打开和关闭,如下源码所示:
int lwip_transport_send_packet_buffer(int sock, unsigned char *buf,
int buflen)
{
int rc = 0;
rc = write(sock, buf, buflen);
return rc;
}
if(server == NULL)
printf("[ERROR] Get host ip failed\n");
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length);
if(connect(*sock,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
{
printf("[ERROR] connect failed\n");
return -1;
}
setsockopt(mysock, SOL_SOCKET, SO_RCVTIMEO,
(char*)&timeout,sizeof(timeout));
return mysock;
}
这些函数是由用户来实现,例如连接函数,根据自己的硬件编写连接。上述的源码小编以LWIP为例。
(3) 订阅和发布操作
void lwip_demo(void)
{
mysock = lwip_transport_open((char *)HOST_NAME, HOST_PORT);
data.clientID.cstring = CLIENTID;
data.username.cstring = USERNAME;
data.password.cstring = PASSWORD;
unsigned char payload_out[200];
int payload_out_len = 0;
uint32_t sendtick = xTaskGetTickCount();
while (1)
{
if ((xTaskGetTickCount() - sendtick) >= (send_duration * 100))
{
sendtick = xTaskGetTickCount();
taskENTER_CRITICAL();
temp = 30 + rand() % 10 + 1;
humid = 54.8 + rand() % 10 + 1;
sprintf((char *)payload_out, "{\"id\": 123,\"dp\":
{ \"temperatrue\": [{\"v\": %0.1f,}],\"power\":
[{\"v\": %0.1f,}]}}", temp, humid);
payload_out_len = strlen((char *)payload_out);
topicString.cstring = DEVICE_PUBLISH;
len = MQTTSerialize_publish((unsigned char *)buf,
buflen, 0, req_qos,
retained, msgid,
topicString,
payload_out,
payload_out_len);
rc = lwip_transport_send_packet_buffer(mysock,
(unsigned char *)buf, len);
taskEXIT_CRITICAL();
if (rc == len)
printf("send PUBLISH Successfully\r\n");
else
printf("send PUBLISH failed\r\n");
printf("send temp(%0.1f)&humid(%0.1f) !\r\n", temp, humid);
recv_server_flag = 1;
}
vTaskDelay(100);
switch (msgtypes)
{
case CONNECT:
printf("进入CONNECT状态\r\n");
len = MQTTSerialize_connect((unsigned char *)buf,
buflen, &data);
rc = lwip_transport_send_packet_buffer(mysock,
(unsigned char *)buf, len);
if (rc == len)
printf("发送连接成功\r\n");
else
printf("发送连接失败\r\n");
printf("MQTT连接服务器!\r\n");
printf("退出CONNECT状态\r\n\r\n");
msgtypes = 0;
recv_server_flag = 1;
break;
case CONNACK:
if (MQTTDeserialize_connack(&sessionPresent,
&connack_rc, (unsigned char *)buf, buflen) != 1
|| connack_rc != 0)
{
printf("Unable to connect, return code %d\r\n", connack_rc);
}
else
{
printf("MQTT is concet OK!\r\n");
}
msgtypes = SUBSCRIBE;
break;
case SUBSCRIBE:
topicString.cstring = DEVICE_SUBSCRIBE;
len = MQTTSerialize_subscribe((unsigned char *)buf,
buflen, 0, msgid, 1, &topicString, &req_qos);
rc = lwip_transport_send_packet_buffer(mysock,
(unsigned char *)buf, len);
if (rc == len)
printf("send SUBSCRIBE Successfully\r\n");
else
{
printf("send SUBSCRIBE failed\r\n");
t++;
if (t >= 10)
{
t = 0;
msgtypes = CONNECT;
}
else
msgtypes = SUBSCRIBE;
break;
}
msgtypes = 0;
recv_server_flag = 1;
break;
case SUBACK:
rc = MQTTDeserialize_suback(&submsgid, 1, &subcount,
&granted_qos, (unsigned char *)buf,
buflen);
printf("granted qos is %d\r\n", granted_qos);
msgtypes = 0;
break;
case PUBLISH:
break;
case PUBACK:
msgtypes = 0;
break;
default:
break;
}
if (recv_server_flag == 1)
{
memset(buf, 0, buflen);
rc = MQTTPacket_read((unsigned char *)buf, buflen,
lwip_transport_getdata);
if (rc > 0)
{
msgtypes = rc;
}
recv_server_flag = 0;
}
}
}
- 下载验证:
|