1.6.4 云端数据解析脚本

优质
小牛编辑
128浏览
2023-12-01

更新时间:2018-09-15 13:44:21

概述

本章节主要针对采用透传/自定义格式上报数据的设备,您如果使用了Alink协议可以跳过,可以直接参考 Alink 协议文档完成设备端的开发和接入,无需编辑数据解析脚本。

Link Develop开发平台为开发者提供了用于数据解析的在线脚本编辑器,方便您进行在线的编辑和模拟调试。

数据解析流程:

image.png | center | 482x393

数据解析将为您提供:

  • 脚本在线编辑器,支持 JavaScript 语言;

  • 支持保存草稿,并从草稿中恢复编辑,支持删除草稿;

  • 支持对脚本的模拟数据调试,可输入上下行数据进行模拟转换,查看脚本运行结果;

  • 支持对脚本的静态语法检查(js语法);

  • 提交脚本到运行环境,在设备上下行时进行调用;

编辑脚本内容

在线编辑脚本
在产品详情页面,点击“数据解析”进入脚本编辑页面,在下方编辑其中编写数据解析脚本,目前支持编写 JavaScript 语言。

image.png | center | 704x384

自动生成脚本
如果您采用平台定义的标准二进制通讯协议,您可以直接点击“自动生成脚本”,此时系统将为您自动生成对应的数据解析脚本,您可以在此基础上进行编辑修改,完成提交。
请注意,脚本是根据您创建的功能进行自动生成的,如果您修改了产品的功能定义,您将需要重新生成脚本或手动进行编辑。

image.png | center | 704x386

全屏编辑草稿
点击“全屏”按钮,页面将自动展开,您可以全屏查看或编辑脚本,点击“退出全屏”即可退出当前编辑界面。

image.png | center | 704x410

保存草稿

如果您编辑过程中需要临时保存草稿,可以点击页面底部的“保存草稿”按钮,系统将保存本次编辑的结果,您下次再进入平台时,将提示您最近一次保存的草稿,您可以选择恢复编辑或删除草稿。

image.png | center | 704x407

image.png | center | 704x410

脚本模拟运行

脚本编辑完成后,您可以在编辑器下方输入模拟数据,验证脚本的运行情况,输入模拟数据后,点击“运行”按钮,系统将首先对脚本进行静态语法检查,语法检查通过后才会调用该脚本进行数据解析。

模拟上行数据解析
选择模拟类型为“设备上报数据”,输入透传二进制数据,点击“运行”按钮,您可以在运行结果区域看到透传数据的解析结果。

image.png | center | 1437x838

模拟设备下行数据解析
选择模拟类型为“设备接收数据”,输入JSON格式数据,点击“运行”按钮,会将JSON数据按照脚本规则转换为二进制数据发送给设备进行执行,您可以在运行结果区域看到解析后的数据。

image.png | center | 704x410

提交脚本

脚本运行通过后,您才可以将脚本提交到运行环境中,设备上下行时将自动调用脚本,实现数据的解析和转换。
请注意,产品发布后将无法再对脚本进行任何编辑和修改,请确保脚本运行无误后再发布产品。

image.png | center | 1438x838

脚本定义

语言定义

目前脚本仅支持符合ECMAScript 5.1的JavaScript语法。

方法定义

Alink协议数据转二进制数据

方法如下:

解析服务端发送的AlinkJson数据,并转换为二进制数据返回
function protocalToRawData(jsonObj){
    return rawdata;
}

参数定义:
输入参数jsonObj :符合产品TSL定义的Alink协议格式数据, 如:

{"method":"thing.service.property.set","id":"12345","version":"1.0","params":{"prop_float":123.452, "prop_int16":333, "prop_bool":1}}

返回参数 :二进制byte数组, 如

0x0100003039014d0142f6e76d

二进制数据转Alink协议数据

方法如下:

解析设备端发送的二进制数据,并转换为AlinkJson数据返回
function rawDataToProtocal(rawData){
    return jsonObj;
}

参数定义:
输入参数rawData :二进制byte数组, 如

0x00002233441232013fa00000

返回参数 :符合产品TSL定义的Alink协议格式数据, 如:

{"method":"thing.event.property.post","id":"2241348","params":{"prop_float":1.25,"prop_int16":4658,"prop_bool":1},"version":"1.0"}

自动生成脚本

通过该功能我们会直接读取TSL数据, 并使用云平台定制的协议直接生成对应的脚本文件。但需要注意的是, 使用该功能时请配套使用为了设备端开发的MCUSDK(使用同一版本定制协议), 详情参考MCUSDK文档

示例demo

相关设备模型操作

在自定义的设备模型中添加属性。

image | center

image | center

image | center

绑定脚本代码

把脚本代码复制到如下输入框中:

参考代码:

image | center

var COMMAND_REPORT = 0x00;
var COMMAND_SET = 0x01;

var ALINK_PROP_REPORT_METHOD = 'thing.event.property.post'; //标准ALink协议topic, 设备 上传属性数据到 云端
var ALINK_PROP_SET_METHOD = 'thing.service.property.set'; //标准ALink协议topic, 云端 下发属性控制指令 到设备端

/*
示例数据:
传入参数 ->
    0x00002233441232013fa00000
输出结果 ->
    {"method":"thing.event.property.post","id":"2241348",
    "params":{"prop_float":1.25,"prop_int16":4658,"prop_bool":1},
    "version":"1.0"}

*/
function rawDataToProtocol(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 = new Object();

    var fHead = uint8Array[0]; // command
    if (fHead == COMMAND_REPORT)
    {
        jsonMap['method'] = ALINK_PROP_REPORT_METHOD; //Alink协议 - 属性上报topic
        jsonMap['version'] = '1.0'; //Alink协议 - 协议版本号固定字段
        jsonMap['id'] = '' + dataView.getInt32(1); //Alink协议 - 标示该次请求id值
        var params = {};
        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协议 - params标准字段
    }

    return jsonMap;
}

/*
示例数据:
传入参数 ->
    {"method":"thing.service.property.set","id":"12345","version":"1.0","params":{"prop_float":123.452, "prop_int16":333, "prop_bool":1}}
输出结果 ->
    0x0100003039014d0142f6e76d

*/
function protocolToRawData(json)
{
    var method = json['method'];
    var id = json['id'];
    var version = json['version'];

    var payloadArray = [];
    if (method == ALINK_PROP_SET_METHOD)    // 属性设置
    {
        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字段
        payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); // Alink协议 'id'
        payloadArray = payloadArray.concat(buffer_int16(prop_int16)); // 属性'prop_int16'的值
        payloadArray = payloadArray.concat(buffer_uint8(prop_bool)); // 属性'prop_bool'的值
        payloadArray = payloadArray.concat(buffer_float32(prop_float)); // 属性'prop_float'的值
    }

    return payloadArray;
}

//以下是部分辅助函数
function buffer_uint8(value)
{
    var uint8Array = new Uint8Array(1);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setUint8(0, value);
    return [].slice.call(uint8Array);
}
function buffer_int16(value)
{
    var uint8Array = new Uint8Array(2);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setInt16(0, value);
    return [].slice.call(uint8Array);
}
function buffer_int32(value)
{
    var uint8Array = new Uint8Array(4);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setInt32(0, value);
    return [].slice.call(uint8Array);
}
function buffer_float32(value)
{
    var uint8Array = new Uint8Array(4);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setFloat32(0, value);
    return [].slice.call(uint8Array);
}

protocolToRawData 的返回值需要是个数组,例如 ["123"]

数据测试

设备上报数据测试数据

0x00002233441232013fa00000

上报数据输出结果

{"method":"thing.event.property.post","id":"2241348",
"params":{"prop_float":1.25,"prop_int16":4658,"prop_bool":1},
"version":"1.0"}

undefined | center

设备接收数据测试数据

{"method":"thing.service.property.set","id":"12345","version":"1.0","params":{"prop_float":123.452, "prop_int16":333, "prop_bool":1}}

接收数据输出结果

0x0100003039014d0142f6e76d

undefined | center

Demo也支持在本地环境中进行调用

// Test Demo
function Test()
{
    //0x001232013fa00000
    var rawdata_report_prop = new Buffer([
        0x00, //固定command头, 0代表是上报属性
        0x00, 0x22, 0x33, 0x44, //对应id字段, 标记请求的序号
        0x12, 0x32, //两字节 int16, 对应属性 prop_int16
        0x01, //一字节 bool, 对应属性 prop_bool
        0x3f, 0xa0, 0x00, 0x00 //四字节 float, 对应属性 prop_float
    ]);

    rawDataToProtocol(rawdata_report_prop);

    var setString = new String('{"method":"thing.service.property.set","id":"12345","version":"1.0","params":{"prop_float":123.452, "prop_int16":333, "prop_bool":1}}');
    protocolToRawData(JSON.parse(setString));
}

Test();