合宙Air202模块连接阿里云物联网平台收发数据

Air202与阿里云物联网平台的上行通道

用到的GPRS模块:合宙Air202用到的物联网平台:阿里云

GPRS模块对接阿里云物联网平台,对于新手来说还是很有难度的。在这里,我将使用合宙air202模块,连接阿里云物联网平台,最终使用自己的阿里云服务器来进行数据的双向通信。


一、阿里云物联网平台创建新设备
1、登录阿里云系统,进入阿里云物联网控制台
2、创建产品,选择高级版,输入产品名称,节点类型选择“设备”,设备类型选择“无”,数据格式选择“Alink JSON”,是否接入网关选择“否”,确认
3、进入刚刚创建的产品,添加设备,输入设备名称DeviceName,建议以无线网络模块的IMEI序列号来命名设备以避免重复,保存后,物联网系统会自动生成该设备证书,包括三个数据,如下所示:
 

二、无线网络模块连接阿里云物联网平台
阿里云物联网平台与设备端支持MQTT通信协议,因此在这里建议无线网络模块采用MQTT协议连接阿里云物联网平台。
MQTT通信协议的底层是TCP通信,因此只要无线模块支持TCP通信,原则上就可以TCP基础上移植MQTT,然而MQTT的协议自己移植的话过于复杂,因此各大无线模组供应商与阿里云合作,纷纷推出了内嵌了阿里云物联网通信协议的通信模组,例如这里使用的是AIR202模组。
air202模组是2G模组,具有较高的性价比。
1、拿到AIR202模组,先确认其固件是否是支持连接阿里云物联网平台的版本,方法是发送AT+CGRM,模块会返回当前固件版本,例如:AirM2M_V5509_AT_S_SSL。只有版本尾号为SSL的固件版本才支持接入阿里云物联网平台。
2、接下来,使用串口助手向air202依次发送一下AT指令
(1)AT //必须发送大写的AT,用来与模组进行波特率的同步。
(2)AT+CGMR//查看模块固件版本,检查尾号是否为SSL,若尾号不是SSL,则需要先使用合宙的LuaTool工具先更新固件,如下图所示:
 
(3)AT+CGATT?  //查看GPRS业务附着情况,附着成功返回1,若返回0则肯定不能联网
(4)AT+SAPBR=3,1,"CONTYPE","GPRS"  //设置网络参数
        AT+SAPBR=3,1,"APN","CMIOT" 
        AT+SAPBR=1,1
(5)AT+CGATT? //检查网络附着情况
(6)AT+HTTPINIT //使用http业务之前,先初始化http协议栈
(7)AT+HTTPPARA="URL","https://iot-auth.cn-shanghai.aliyuncs.com/auth/devicename"  //设置http参数
        AT+HTTPPARA="USER_DEFINED","Content-Type: application/x-www-form-urlencoded"
        AT+HTTPDATA=112,20000  //注意这里的数字112是下面一条数据的总字节个数
(8)productKey=a1jRE6oEtOv&sign=773c0feaab4109a153cf07f3dcef3356&clientId=869300031656865&deviceName=869300031656865
        productKey是阿里云物联网平台系统自动为你创建的产品产生的一个参数。如下所示:
 

      clientId与deviceName在这里设置为相同的数据,来自物联网平台用户添加设备时输入的设备名称,例如这里都是869300031656865,如下图所示:
 
    sign参数的来头就稍微复杂了一点,它是使用hMacMd5算法计算出来的一个哈希值。
前期测试,可以使用现成的工具来进行计算,例如使用一个在线计算器,链接:http://tool.oschina.net/encrypt?type=2
界面如下所示:
 
在上面的小工具输入明文为:clientId862991419835241deviceName862991419835241productKeyb1KCi45LcCP
注意,输入的明文里的clientId与deviceName应该与被注册的设备信息保持一致,productKey应与被注册的产品信息一致。检查一下,不要有多余的空格符。
这里要注意下,上面小工具需要输入一个密钥,该密钥为被注册的这个设备的DeviceSecret,如下图所示:
 
最终计算出一个哈希值,该值就是上面步骤(8)中的sign。
(9)AT+HTTPACTION=1 //http方式激活,该AT指令发送后稍微等几秒,模块回复+HTTPACTION: 1,200,128
(10)AT+HTTPREAD //查询http数据响应,一切正常的话,此时模块应该返回与阿里云物联网平台进行鉴权后的数据结果,其中包括iotId、iotToken和success成功提示
(11)AT+HTTPTERM //结束http服务
(12)AT+MCONFIG="869300031656865","这里输入上面步骤10返回的iotId","这里输入上面步骤10返回的iotToken"  //设置MQTT相关参数
         这里注意,每次执行步骤10后获取到的iotToken值都不一样,都需要重新更新步骤12中的iotToken。
(13)AT+SSLMIPSTART="这里应该是你产品的的ProducKey.iot-as-mqtt.cn-shanghai.aliyuncs.com",1883   
    //例如AT+SSLMIPSTART="a1jRE6oEtOv.iot-as-mqtt.cn-shanghai.aliyuncs.com",1883,这条指令发送完后要等几秒,模块回复“CONNECT OK”
(14)AT+MCONNECT=1,300 //客户端向服务器请求会话连接,返回CONNACK OK说明连接成功
(15)AT+MSUB="/a1jRE6oEtOv/869300031656865/user/get",0  //这条指令用于订阅一个topic,请参考自己平台下某个设备的可用topic进行修改,若            订阅成功系统返回“SUBACK”。
截止到此,采用air202的设备端就已经成功与阿里云物联网平台进行了mqtt长连接。
此时从阿里云物联网平台查看设备,会发现该设备处于“在线”状态,如下所示:
 

三、设备端发送数据至服务器设备端与阿里云物联网平台成功连接后,设备端就可以向平台的某个具备发布权限的Topic发送数据了,例如在这里,设备将向/a1jRE6oEtOv/868575026616807/user/update发布数据。

想要发布的数据为JSON格式如下所示:
{
  "cmd":"get one code"
}
然而,在使用AT指令将JSON格式的数据发送到模组时,需要对上面的JSON格式数据字符串进行相应的改变,方法是将双引号“修改为\22,
因此需要发送的AT指令为:
AT+MPUB="/a1jRE6oEtOv/868575026616807/user/update",1,0,"{\22cmd\22:\22get one code\22}"
数据发送成功后,模组会返回:“PUBACK”,这说明阿里云物联网平台已经收到数据,此时我们登录阿里云物联网平台,进入该设备所对应的产品类目下,查看“日志服务”-->"上行消息分析",可以看到通信成功的界面,如下所示: 
然而,虽然物联网平台能够接收到来自设备端上传的数据,但是我们的服务器根本是不知道设备发来的是什么数据,想要让设备端上传的数据能够发送到自己的服务器,则中间必须要用到阿里云物联网的中间件,其实就是一个阿里云的数据转发中间件,
该中间件可以按照用户需求对数据做过滤处理,并最终按照用户设置的参数将数据转发到目的地,这个数据转发服务阿里云是收费的。具体的流程如下所示:
设备端发送数据---->阿里云物联网平台接收到设备端数据---->规则引擎对接收到的数据做过滤提取------>提取出来的数据被转发到MQ消息队列---------->用户服务器监听MQ消息队列中的数据--------->监听到数据则执行回调函数进行业务处理

1、启用MQ消息队列服务,并创建一条Topic
     进入MQ消息队列控制台,点击“创建Topic”,输入Topic名称,此处的Topic需自己取名;消息类型按需选取,再此我选择普通消息。
     对刚刚创建的Topic进行授权设置,设置为授予订阅权限,这样我们的服务器就可以订阅这条Topic来监听转发过来的数据。
     为刚刚创建的Topic创建生产者与消费者,名称需要自己明明。
2、创建规则引擎并编写SQL语句
     打开阿里云物联网平台控制中的规则引擎,创建规则,输入规则名称,选择JSON格式,保存。
     点击“管理”,编辑SQL语句,如下所示:
 
字段输入为*,表明我将设备端上传的JSON数据为全部选择。
Topic处为"+/user/update",表明这条规则只处理满足+/user/update格式的数据。
条件处为空,表明没有条件限制。
保存该SQL语句.
3、配置规则引擎中的转发数据目的地
打开上面步骤中设置的那条SQL语句对应的管理界面,界面下方点击“添加操作”,
选择操作为“发送数据到消息队列”,其他配置如下图所示:
 
保存之后,启用该条转发规则,系统提示成功。
3、服务器端运行Demo进行数据监听测试
服务端采用JAVA,源码如下:

  1. package com.aliyun.iot.demo;

  2. import com.aliyun.openservices.ons.api.Action;
  3. import com.aliyun.openservices.ons.api.ConsumeContext;
  4. import com.aliyun.openservices.ons.api.Consumer;
  5. import com.aliyun.openservices.ons.api.Message;
  6. import com.aliyun.openservices.ons.api.MessageListener;
  7. import com.aliyun.openservices.ons.api.ONSFactory;
  8. import com.aliyun.openservices.ons.api.PropertyKeyConst;

  9. import java.io.UnsupportedEncodingException;
  10. import java.util.Properties;

  11. public class H2 {

  12.         public static void main(String[] args) {

  13.                 Properties properties = new Properties();
  14.                 // 这里的ConsumerId参数是你在MQ消息队列控制台创建的Topic时,你创建的消费者名称
  15.                 properties.put(PropertyKeyConst.ConsumerId, "CID_lockDevice");

  16.                 // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建
  17.                 properties.put(PropertyKeyConst.AccessKey, "改成你自己的");

  18.                 // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建
  19.                 properties.put(PropertyKeyConst.SecretKey,"改成你自己的");

  20.                 // 设置 TCP 接入域名(此处以公共云生产环境为例)
  21.                 // http://onsaddr-internet.aliyun.com/rocketmq/nsaddr4client-internet
  22.                 properties.put(PropertyKeyConst.ONSAddr,"http://onsaddr-internet.aliyun.com/rocketmq/nsaddr4client-internet");
  23.                 // 集群订阅方式 (默认)
  24.                 // properties.put(PropertyKeyConst.MessageModel,
  25.                 // PropertyValueConst.CLUSTERING);
  26.                 // 广播订阅方式
  27.                 // properties.put(PropertyKeyConst.MessageModel,
  28.                 // PropertyValueConst.BROADCASTING);
  29.                 Consumer consumer = ONSFactory.createConsumer(properties);
  30.                 // 下面函数中的参数qmlock_meg为MQ控制台创建的Topic名称;第二个参数为星号,表明监听所有数据
  31.                 consumer.subscribe("qmlock_meg", "*", new MessageListener() {
  32.                         @Override
  33.                         public Action consume(Message message, ConsumeContext context) {
  34.                                 System.out.println("Receive: " + message);
  35.                                 String res = null;
  36.                                 byte[] resByte = message.getBody();//获取消息体
  37.                                 try {
  38.                                         res = new String(resByte, "UTF-8");//将消息体byte型数据转换成字符串
  39.                                 } catch (UnsupportedEncodingException e) {
  40.                                         // TODO Auto-generated catch block
  41.                                         e.printStackTrace();
  42.                                 }
  43.                                 System.out.println("body: " + res);//打印消息体
  44.                                 return Action.CommitMessage;//返回消息消费结果
  45.                         }
  46.                 });
  47.                 consumer.start();
  48.                 System.out.println("Consumer Started");
  49.         }
  50. }
复制代码

服务端启动运行后,控制台显示“Consumer Started”,并处于监听状态。
此时,登录MQ控制台,查看消费者状态,如下图所示:
 
上图中,“是否在线”、“订阅关系是否一致”都显示“是”,表明服务端成功开启监听。
进入MQ消息队列控制台,打开生产者管理,发送消息里输入消息体“hello world”并发送,显示发送成功,此时查看服务端控制台,显示出已经接受到消息,如下所示:
 
   MQ控制台发送消息,服务端能够成功接收,说明服务端监听正常。
接下来,使用air202模组,发送AT+MPUB="/a1b96wWfb8u/868575026616807/user/update",1,0,"{\22cmd\22:\22get one code\22}"
服务端收到数据如下所示:
 

  • 发表于 2018-09-30 10:45
  • 阅读 ( 13225 )

你可能感兴趣的文章

相关问题

4 条评论

请先 登录 后评论
不写代码的码农
老张

知识搬运工

14 篇文章

作家榜 »

  1. 技术销售Delectate 43 文章
  2. 陈夏 26 文章
  3. 国梁 24 文章
  4. miuser 21 文章
  5. 晨旭 20 文章
  6. 朱天华 19 文章
  7. 金艺 19 文章
  8. 杨奉武 18 文章