监测现场实时数据上传到中移物联网OneNet云平台

        OneNet,中移物联网云平台,是由中国移动打造的PaaS物联网开放平台。平台能够帮助开发者轻松实现设备接入与设备连接,快速完成产品开发部署,为智能硬件、智能家居产品提供完善的物联网解决方案(摘自360百科)。实际监测环境中,平台一般是前端监测设备和后台软件产品的一个桥梁,现场设备数据通过RTU(数据传输单元)并以平台可以接受的MQTT协议,上传到OneNet云平台;后台软件可以在该平台上获取相关数据进行解算、显示。这是主流的使用方法,现在很多RTU都支持将数据接入到OneNet平台,网上也有很多相关的介绍。但是现在,由于前端数据经过RTU只是原始数据,底层难以实现数据解算,而后台软件开发方又需要初步解算过的数据。

        因此我们想了一个方案,通过我们自己的服务器中转,在本地服务器进行数据解算之后,按照软件开发方要求的数据格式和他们给的设备注册号等信息上传到OneNet云平台。为了方便,我们在做测试的时候,自己先在OneNet云平台上注册了账号,有了自己的开发者中心。这样创建的产品、注册的设备、上传的数据都能看得见,方便观察效果。整个数据上传的测试过程包括以下几个步骤:

 1)首先是要有一个自己的开发者中心。

1.1 注册账号

1.2 创建产品

这两步在OneNet的这个开发文档中解释得很清楚:https://open.iot.10086.cn/doc/art243.html#66

现在我们在云平台上有了自己的产品,类似于有了一个数据上传中心。在开发者中心首页,可以看到自己的产品列表,我这里有 两个产品,用于测试的产品仅仅是test1这个产品,创建的时候我选择的是MQTT协议,这个可以根据需求选择,上文链接中的 文档也有简单介绍。我将会把数据上传到test1产品下面。

监测现场实时数据上传到中移物联网OneNet云平台_第1张图片

创建产品之后,系统会生成一个产品ID、APIKey和正式环境注册码,正式环境注册码将在后面注册设备的时候用到。

监测现场实时数据上传到中移物联网OneNet云平台_第2张图片

监测现场实时数据上传到中移物联网OneNet云平台_第3张图片

1.3 注册设备

        一般都是指现场RTU接入的设备,我们现场有5台独立设备。在这里我们模拟现场,在平台上注册了5台设备。但实际上,数据却是从我们自己本地的服务器上传过去的,相当于本地服务器上的数据上传程序充当了5台虚拟设备,往云平台推送数据; 也可以理解为程序仅仅是一个中转过程。本文的重点就在于如何通过软件编程语言将数据推送至云平台

    测试的时候注册设备很简单,也是通过在自己的产品test1下面手动创建(后面会讲到在没有条件手动创建的时候,如何动态创建):

监测现场实时数据上传到中移物联网OneNet云平台_第4张图片

输入设备名称和鉴权信息即可,一般这两项客户方都会要求按照一定的格式命名,最终将注册后的参数上报过去。在实际操作过程中,我们就遇到了命名不符合要求的情况,重新命名注册后,系统返回的设备ID和APIKey也会改变,还是挺麻烦的。这里测试就不用管那么多,注意一下系统返回的设备IDAPIKey就好,后面上传数据会用到。

监测现场实时数据上传到中移物联网OneNet云平台_第5张图片

以上,我们以注册的名为LGLK_ZSD1800324的设备为例,系统返回设备IDAPIKey,后续会用到。可以看到,刚注册的设备数据展示还是0,没有传入任何数据:

监测现场实时数据上传到中移物联网OneNet云平台_第6张图片

    至此,我们已经有了上传数据的一切条件,要用到的就是设备IDAPIKey,要得到这两项,前面的步骤一个都省不掉。另外,用户在新的设备中,不需要提前创建数据流,因为当用户使用协议上传数据点的时候,平台会自动创建数据流,采用这样的方式就能省去数据流创建工作。


    以上,我们就有了基于OneNet云平台的以下条件:

产品(含产品ID、产品ID、APIKey、正式环境注册码)——>产品下的设备(含设备ID、APIKey)——>设备下的数据流datastream(可选,一般不推荐手动创建)。

2)终于到了数据上传软件这一块了。因为以前接触过TCP通信,这次在编写C++软件程序的时候,我还是选择了C++中的SOCKET通信,向云平台发送HTTP协议的数据上传报文。其实编写数据上传软件,软件是client端,负责发送数据并不难,抓住socket TCP通信client端的主要步骤即可(这些内容在网上也有很多介绍):

1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置要连接的对方的IP地址和端口等属性;
5、连接服务器,用函数connect();

6、收发数据,用函数send()和recv(),或者read()和write();

7、关闭网络连接;

这些步骤要一步步落实,第4步“设置要连接的对方的IP地址和端口等属性”,设置的IP地址是OneNet公开协议接入指南http接入要连接到IP 183.230.40.34,端口80。使用Send()函数发送到指定上述地址的时候,要注意数据格式一定是按照规定的格式。

 我用到的数据上传报文如下:

  1. POST /devices/29866262/datapoints?type=3 HTTP/1.1
  2. api-key: k3EQjLNqBKUej=IR9I7c6tLsZkM=
  3. Host:api.heclouds.com
  4. connection: close
  5. Content-Length:65
  6. {"datastreams":[{"id":"temperature","datapoints":[{"value":0}]}]}

以上报文需要注意的是:第一行的设备ID29866262替换成你自己的设备ID;第二行设备的api-key替换成自己的设备api-key;第4行这个参数决定了你发送完这段报文之后是保持TCP继续连接还是断开连接。我第一次就是按照默认的close,结果数据只能上传一次,后来发现这个的时候,才醒悟过来,就把这行代码去掉了。就是说发送完一次数据之后,继续保持连接,因为实时数据会源源不断地上传,必须保持连接。第5行指的是第7行数据的长度,这个不允许出错,但是也不需要一个个数,在word文档里可以计数

监测现场实时数据上传到中移物联网OneNet云平台_第7张图片

以防数错。而且在C++代码里,是有strlen()这么一个函数,可以输出char*数组的字符数的。这样就能保证精确度,这个长度错了,上传的报文云端也是没法解析的,会报错。还有就是第5行之后有一个空行,在C++代码里换行\r\n就要加上两个了,切记。

这段数据上报成功,系统设备下面就会自动创建temperature数据流,值为0。我先是用的TCP网络调试助手做的实验。网络调试助手实际上就是用TCP的SOCKET通信完成数据上传和接收的。我们可以看到云平台返回{“errno":0;“error":"succ"},说明数据上传成功,并且自动创建了数据流:

监测现场实时数据上传到中移物联网OneNet云平台_第8张图片

设备数据状态:

监测现场实时数据上传到中移物联网OneNet云平台_第9张图片

数据内容:

监测现场实时数据上传到中移物联网OneNet云平台_第10张图片

    以上只是用TCP网络调试助手做了个测试,数据上传成功,说明数据报文是没有问题的。后面就是用代码实现了,直接上代码:

//相关变量定义
//1、TCP连接地址和端口号
char* host = "183.230.40.34";
int port = 80;
char* addr = "api.heclouds.com";
//2、上传数据post HTTP报文
char* pHttpPost = "POST %s HTTP/1.1\r\n"
"api-key:%s\r\n"
"Host: %s\r\n"
"Content-Length: %d\r\n\r\n"   //两个“\r\n”
"%s";
char* URL= "http://api.heclouds.com/devices/29866262/datapoints?type=3";//给设备ID为29866262的设备上传Type=3格式的数据
char* msg = "{\"datastreams\":[{\"id\":\"001_1\",\"datapoints\":[{\"value\":%d}]}]}";//数据格式,Type=3
//3、设备的APIKey
char* api_key = "k3EQjLNqBKUej=IR9I7c6tLsZkM=";

//定义了一个ClientNet类的变量client,在该类内完成和云平台的连接、发送数据等函数
client.Connect(port, host); //连接到云平台
//数据上传
char strTemp[BufferLen];
sprintf(strTemp, "%s", URL);//把char*的URL参数改为char型数组格式
char strHttpPost[BufferLen];//存储上传数据的最终报文
char rainArray[BufferLen];//
char msgArray[BufferLen];
sprintf(msgArray, msg0, RealRainfall*0.2);//实时数据以msg0的格式传给msgArray
sprintf(strHttpPost, pHttpPost, strTemp, api_key, addr, strlen(msgArray), msgArray);//生成最终的HTTP报文
//发送数据报文
client.SendMsg(strHttpPost, strlen(strHttpPost));

client.Close();//关闭连接

以上截取的是代码片段,其中涉及到的ClienNet类的构建,详见附件。至此,基本完成软件和云平台的连接、数据上传工作。


你可能感兴趣的:(监测现场实时数据上传到中移物联网OneNet云平台)