阿里云物联网平台-数据解析脚本详解

阿里云物联网平台-数据解析脚本详解

var COMMAND_REPORT = 0x00; //属性上报。
var COMMAND_SET = 0x01; //属性设置。
var COMMAND_REPORT_REPLY = 0x02; //上报数据返回结果。
var COMMAND_SET_REPLY = 0x03; //属性设置设备返回结果。
var COMMAD_UNKOWN = 0xff;    //未知的命令。

定义五个参数,分别在后面的解析函数中用到。

var ALINK_PROP_REPORT_METHOD = 'thing.event.property.post'; //物联网平台Topic,设备上传属性数据到云端。
var ALINK_PROP_SET_METHOD = 'thing.service.property.set'; //物联网平台Topic,云端下发属性控制指令到设备端。
var ALINK_PROP_SET_REPLY_METHOD = 'thing.service.property.set'; //物联网平台Topic,设备上报属性设置的结果到云端。

var SELF_DEFINE_TOPIC_UPDATE_FLAG = '/user/update'  //自定义Topic:/user/update。
var SELF_DEFINE_TOPIC_ERROR_FLAG = '/user/update/error' //自定义Topic:/user/update/error。

定义请求方法method参数的值,详见阿里云 <设备属性、事件、服务> 文档

设备属性、事件、服务

<函数一>
/**  * 将设备的自定义格式数据转换为Alink协议的数据,设备上报数据到物联网平台时调用  
       * 入参:rawData byte[]数组     不能为空  
       * 出参:jsonObj Alink JSON对象 不能为空  */
function rawDataToProtocol(bytes) {
    var uint8Array = new Uint8Array(bytes.length);
    for (var i = 0; i < bytes.length; i++) {
        uint8Array[i] = bytes[i] & 0xff;
    }
 /*将设备上报的原始数据转换为数组。其中bytes对象中存储着设备上报原始数据。*/
 
    var dataView = new DataView(uint8Array.buffer, 0);
    var jsonMap = new Object();
    var fHead = uint8Array[0]; // 第0个字节00,
    if (fHead == COMMAND_REPORT) {//判断第0个字节是否等于属性上报标识符,也就是说属性上报第0个字节必须为00(自己前面定义的十六进制).
        jsonMap['method'] = ALINK_PROP_REPORT_METHOD; //ALink JSON格式,属性上报topic。method='thing.event.property.post
        jsonMap['version'] = '1.0'; //ALink JSON格式,协议版本号固定字段。
        jsonMap['id'] = '' + dataView.getInt32(1); //ALink JSON格式,标示该次请求id值。
        var params = {}; // 定义属性存放对象。
        var jsonMap = {}; 
        params['prop_int16'] = dataView.getInt16(5); //对应产品属性中prop_int16。 
        params['prop_bool'] = uint8Array[7]; //对应产品属性中prop_bool。
        params['prop_float'] = dataView.getFloat32(8); //对应产品属性中prop_float。
        jsonMap['params'] = params; //ALink JSON格式,params标准字段。将参数打包到数据帧中。
    } 
else if(fHead == COMMAND_SET_REPLY) {//判断第0个字节是否等于属性设置设备返回结果
        jsonMap['version'] = '1.0'; //ALink JSON格式,协议版本号固定字段。
        jsonMap['id'] = '' + dataView.getInt32(1); //ALink JSON格式,标示该次请求id值。
        jsonMap['code'] = ''+ dataView.getUint8(5);
        jsonMap['data'] = {};
    }
    return jsonMap;
}

这段代码里面最重要的就是dataView.getInt16()与uint8Array[];
dataView.getInt16()是dataView中的内置函数,用于在指定位置(即,距dataView起始字节偏移)获取16位整型。uint8Array[]则是直接取字节。
例如:
在这里插入图片描述

  1. dataView.getInt32(1),从第一个字节开始取32位整型转化为十进制,如上图所示,四个字节为32位,也就是00000001,十六进制转为十进制,id=1。

  2. params[‘prop_int16’] = dataView.getInt16(5); //对应产品属性中prop_int16。
    从第五个字节开始,取16位整型。也就是第5和第6个字节。0032->50(十进制)。 params[‘prop_bool’] =50。

  3. params[‘prop_bool’] = uint8Array[7];
    //对应产品属性中prop_bool。直接取字节,第七个字节,注意字节要从第0个开始计数。第七个字节为01。

  4. params[‘prop_float’] = dataView.getFloat32(8);
    //对应产品属性中prop_float。从第8个字节开始,取32位浮点型。也就是第8、第9、第10、第11个字节。00000000->0(十进制)。

<函数二>
/*云端下发指令解析函数*/
function protocolToRawData(json) {
    var method = json['method'];
    var id = json['id'];
    var version = json['version'];
    var payloadArray = [];
    if (method == ALINK_PROP_SET_METHOD) //属性设置。云端下发属性控制指令到设备端的这个物模型topic。接收来自物联网平台的“设置设备属性”的命令。
    {
        var params = json['params'];
        var prop_float = params['prop_float'];
        var prop_int16 = params['prop_int16'];
        var prop_bool = params['prop_bool'];//将设置的具体值抽取出来。
        //按照自定义协议格式拼接 rawData。
        payloadArray = payloadArray.concat(buffer_uint8(COMMAND_SET)); //command字段。属性设置。01
        payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); //ALink JSON格式 'id'。配置32位的int整型id。12345->00 00 30 39
        payloadArray = payloadArray.concat(buffer_int16(prop_int16)); //属性'prop_int16'的值。配置16位的int整型。333->01 4d
        payloadArray = payloadArray.concat(buffer_uint8(prop_bool)); //属性'prop_bool'的值。配置8位的无符号int整型。1->01 
        payloadArray = payloadArray.concat(buffer_float32(prop_float)); //属性'prop_float'的值。配置32位的浮点型。754标准
    } 
else if (method ==  ALINK_PROP_REPORT_METHOD) { //设备上报数据返回结果。
        var code = json['code'];
        payloadArray = payloadArray.concat(buffer_uint8(COMMAND_REPORT_REPLY)); //command字段。上报数据返回结果。
        payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); //ALink JSON格式'id'。
        payloadArray = payloadArray.concat(buffer_uint8(code));
 } 
else { //未知命令,对于这些命令不做处理。
        var code = json['code'];
        payloadArray = payloadArray.concat(buffer_uint8(COMMAD_UNKOWN)); //command字段。
        payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); //ALink JSON格式'id'。
        payloadArray = payloadArray.concat(buffer_uint8(code));
 }
    return payloadArray;
}

payloadArray.concat();这个函数就是取相应的位数进行拼接。
例如 :在这里插入图片描述

  1. payloadArray = payloadArray.concat(buffer_int32(parseInt(id)));
    //配置32位的int整型id。12345->00 00 30 39,十进制转十六进制即可。
  2. payloadArray = payloadArray.concat(buffer_int16(prop_int16));
    //属性’prop_int16’的值。配置16位的int整型。333->01 4d
  3. payloadArray = payloadArray.concat(buffer_uint8(prop_bool));
    //属性’prop_bool’的值。配置8位的无符号int整型。1->01
  4. payloadArray = payloadArray.concat(buffer_float32(prop_float));
    //属性’prop_float’的值。配置32位的浮点型。
    唯一比较难算的就是拼接浮点型了,按照754标准拼接即可。
<函数三>
/**
 * 将设备自定义topic数据转换为json格式数据, 设备上报数据到物联网平台时调用
 * 入参:topic   字符串,设备上报消息的topic     
 * 入参:rawData byte[]数组                  不能为空
 * 出参:jsonObj JSON对象                    不能为空
 */
function transformPayload(topic, bytes) {
    var uint8Array = new Uint8Array(bytes.length);
    for (var i = 0; i < bytes.length; i++) {
        uint8Array[i] = bytes[i] & 0xff;
    }
    var dataView = new DataView(uint8Array.buffer, 0);
    var jsonMap = {};
    if(topic.includes(SELF_DEFINE_TOPIC_ERROR_FLAG)) {
        jsonMap['topic'] = topic;
        jsonMap['errorCode'] = dataView.getInt8(0)
    } 
else if (topic.includes(SELF_DEFINE_TOPIC_UPDATE_FLAG)) {
        jsonMap['topic'] = topic;
        jsonMap['prop_int16'] = dataView.getInt16(5);
        jsonMap['prop_bool'] = uint8Array[7];
        jsonMap['prop_float'] = dataView.getFloat32(8);
    }
    return jsonMap;
}

和之前一样,唯一的就是topic是自定义topic时使用这个函数。

自定义topic数据解析:

  • 仅华东2(上海)、华北2(北京)、华南1(深圳)地域支持自定义Topic数据解析。
  • 仅通过MQTT协议接入的设备支持自定义Topic数据解析。 仅解析设备上报云端的数据,不解析云端下行数据。
  • 解析上报数据的Payload,并返回解析后的Payload。
  • 解析前后,数据所在Topic不变。例如,设备发送到/ p r o d u c t K e y / {productKey}/ productKey/{deviceName}/user/update的数据,解析后仍在该Topic中。
  • 配置设备端时,需在发布消息的自定义Topic后添加数据解析标记?_sn=default。物联网平台仅解析设备通过携带标记的Topic发布的数据。在物联网平台创建自定义Topic时按正常Topic定义,不添加该解析标记。
  • 如果产品的数据格式为透传/自定义,还需编写物模型数据解析脚本。
    自定义解析的时候数据脚本中transformPayload函数必须定义,而且内部需要解析指令。

物模型数据解析

  • 设备端也应该选择物模型的topic
  • 属性为默认模块属性,若使用物模型自定义模块,标识符(identifier)的格式为模块标识符:属性标识符。例如,

model1:prop_int16 。

  • 数据格式选择为透传/自定义。
  • 物模型数据解析的时候数据脚本中transformPayload函数也需要定义,但是可以只定义一个空函数即可,不必往里面写东西。
  • 10
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值