版本 修订记录 日期 修订者
1.0 初稿 2019-07-31 翟智刚

[TOC]

1、升级文件说明

FUOTA.obin源文件示例
{"otaFile":{
   "bin_dic":{
      "0":{
               "index":0,
               "buffer":"AgAEAKoDMgQAAAA=",
               "bufferstring":"02 00 04 00 AA 03 32 04 00 00 00"
              },
      "1":{
               "index":0,
               "buffer":"AgAEAKoDMgQAAAA=",
               "bufferstring":"02 00 04 00 AA 03 32 04 00 00 00"
              },
      "2":{
               "index":0,
               "buffer":"AgAEAKoDMgQAAAA=",
               "bufferstring":"02 00 04 00 AA 03 32 04 00 00 00"
              },
      "3":{
               "index":0,
               "buffer":"AgAEAKoDMgQAAAA=",
               "bufferstring":"02 00 04 00 AA 03 32 04 00 00 00"
              },
      "4":{
               "index":0,
               "buffer":"AgAEAKoDMgQAAAA=",
               "bufferstring":"02 00 04 00 AA 03 32 04 00 00 00"
              },
    },
  "devEUI":[{"deveui_start":"0000000000000000","deveui_end":"0000000000000000"}],
  "otaMode":"ota",
  "otaPort":201,
  "packets":5,
  "intervalTime":5000,
  "txCounts":1,
  "swtime":2000,
  "src":null,
  "deviceIntervalTime":60000,
  "dndata":null,
  "appeui":"d896e0efff000000"}
}
.obin文件字段说明
参数 说明
bin_dic 待升级数据总包,由多包(子对象)构成。子对象key从0开始。
bufferstring 剔除空格后作为单播内容发送。
devEUI 待升级节点devEUI范围。这个范围内的节点都需要升级。
otaPort 下行端口和上行端口。目前都是201
packets 升级文件分几包发送。值等于bin_dic的子对象个数,及包数。
intervalTime 两个包发送的时间间隔。单位为毫秒。
deviceIntervalTime 一个节点升级完成后,等待下一个节点升级的间隔。单位为毫秒。
appeui 对应linkwan的joineui,可以做校验

说明:

  • 其他属性FUOTA升级时暂不需要。

  • 所有节点顺序升级。一个节点升级完成,再升级下一个节点。

  • 一个节点的多个数据包,顺序发送。每个数据包至少发两遍(次数可配置)。

  • 所有下发的数据包,内容取bufferstring字符串去掉空格,使用unconfirmed包,端口为otaPort。

  • 判断一个节点升级成功的方法:在下发完所有数据包后,等待一段时间(可配置),收到此节点从otaPort端口有上行数据包,则升级成功;否则,升级失败。

  • LinkWan的SendUnicastCommand接口,数据包长度最大128个16进制字节。

201端口返回结果说明
节点升级成功后,201端口返回的数据
{
  "devAddr": "66ae8469",
  "rssi": -103,
  "data": "8104000000FCFF008102130C16000240081820284733D00200000000",
  "gwEui": "d896e0fff0105d0a",
  "fcnt": 6,
  "devEui": "d896e00005000151",
  "joinPermissionId": 3674,
  "mtype": 2,  //0:join包,2:unconfirmed up 4:confirmed up
  "datr": "SF9BW125",
  "fport": 201,
  "joinEui": "d896e0e000006946",
  "snr": 8.0,
  "time": 1569296961047,
  "nodeGroupId": "102"
}
特别说明:下面是入网返回的数据,fport不存在,注意异常保护
{
  "devAddr": "66ae8469",
  "joinPermissionId": 3674,
  "mtype": 0,
  "rssi": -101,
  "datr": "SF10BW125",
  "joinEui": "d896e0e000006946",
  "snr": 13.0,
  "gwEui": "d896e0fff0105d0b",
  "time": 1569296837194,
  "nodeGroupId": "102",
  "devEui": "d896e00005000151"
}
data十六进制数据含义说明
索引 内容 含义 备注
0 81 固定为81,表示Fuota升级完成。暂不使用。
1 04
2 00
3 00
4 00
5 FC
6 FF
7 00 0表示Fuota升级成功,1表示Fuota升级失败。
8 81 低4位:Fuota版本号;高4位:硬件类型低4位值 从8~15,对应app参数的前8个字节
9 02 硬件类型高8位,因此硬件类型为:28,即40。硬件类型共12位长度。
10 13 高4位:硬件版本1。低4位:3*4=12,表示从app参数索引12开始的字节数。
11 0C 软件版本号:12
12 16 设备类型低8位 22:天鹅制冷热泵
13 00 设备类型高8位
14 02 业务参数版本号,也就是obin文件的版本号
15 40
16 08 485通信波特率除以1200,8表示波特率为9600 16~,对应APP参数第12个字节开始的内容,字节数=索引10的低4位*4
17 18 bit0-bit3:数据位;bit4-bit5:停止位;bit6-bit7:校验位
18 20 bit0:485始终处于接收状态;bit1:电池供电;bit2:使用Uart1;bit3:读取超时;bit4-bit6:上传模式
19 28 confirmDuty
20 47
21 33 透传端口
22 D0 自动复位时间,低8位。单位为小时。 2D0表示每720个小时DTU会自动复位
23 02 自动复位时间,高8位。单位为小时。
24 00
25 00
26 00
27 00

说明:obin文件中从第二包数据的第8个字节开始,共16个字节,应该与201端口上来的数据第9个字节开始共16个字节的数据完全一致。升级成功的判断条件为:索引7内容为0,并且索引14的内容等于obin文件packet1的第14个字节内容(packet1的索引13)

升级结果转义JS脚本入参与返回json对象

入参:

//注入一个packet1参数,取值为obin文件中otaFile.bin_dic.1.bufferstring字符串;
packet1 = "08 00 00 02 00 00 00 81 02 13 0C 16 00 02 70 08 18 20 28 47 33 D0 02 00 00 00 00 55 00 84 02 16 05 05 06 00 0F 04 01 0D 09 00 00 01 00 05 00 0A 00 E8 03 64 00 FF FF FF FF FF 01 03 00 17 22 18 C8 B8 6B 00 00 00 00 00 00 00 00 00 00 2C 01 01 00 00 00";
//201端口返回的data数据
data201="8104000000FCFF008102130C16000240081820284733D00200000000",

返回结果:

{
    "code":1,
    "result":{
        "fuotaVersion":1,
        "hardwareType":40.0,
        "hardwareVersion":1,
        "softwareVersion":12.0,
        "deviceType":22.0,
        "bizParamVersion":2.0,
        "info":"{\"app12Size\":{\"name\":\"app索引12开始的字节数\",\"value\":12},\"baudrate\":{\"name\":\"485通信波特率\",\"value\":9600},\"dataBits\":{\"name\":\"数据位\",\"value\":8},\"stopBits\":{\"name\":\"停止位\",\"value\":1},\"checkBits\":{\"name\":\"校验位\",\"value\":0},\"stats485\":{\"name\":\"485始终处于接收状态\",\"value\":0},\"battery\":{\"name\":\"电池供电\",\"value\":0},\"uart1\":{\"name\":\"使用Uart1\",\"value\":0},\"readTimeout\":{\"name\":\"读取超时\",\"value\":2},\"uploadMode\":{\"name\":\"上传模式\",\"value\":40},\"confirmDuty\":{\"name\":\"confirmDuty\",\"value\":40},\"transformPort\":{\"name\":\"透传端口\",\"value\":51},\"autoResetInterval\":{\"name\":\"自动复位时间(单位:小时)\",\"value\":720},\"data\":{\"name\":\"data\",\"value\":\"8104000000FCFF008102130C16000240081820284733D00200000000\"}}"
    }
}
转换js脚本
/**
 * 转换升级时201或214端口返回的数据
 * @param packet1 obin文件中otaFile.bin_dic.1.bufferstring字符串;
 * @param up_data 201或214端口返回的json中的data段
 * @returns {{code: number}} 0升级失败;1升级成功
 */
function change(packet1, up_data, fport) {

    var change201 = function (data) {
        var result = {};
        //data内容
        //0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
        //81 04 00 00 00 FC FF 00 81 02 13 0C 16 00 02 40 08 18 20 28 47 33 D0 02 00 00 00 00
        var tmp = 0;
        //Fuota版本号
        result.fuotaVersion = data[8] & 15;
        tmp = data[8]>>4;
        //>>0操作只是为了去掉整数小数点后面的0
        //硬件类型
        result.hardwareType = tmp + data[9]*16;
        //硬件版本号
        result.hardwareVersion = data[10] >> 4;
        //硬件版本号
        result.softwareVersion = data[11];
        //设备类型
        result.deviceType = data[12] + data[13]*256;
        //业务参数版本号
        result.bizParamVersion = data[14];
        var info = {};
        info.app12Size = {name:"app索引12开始的字节数", value: (data[10] & 15)*4};
        //app从第12个字节开始的内容
        info.baudrate = {name:"485通信波特率", value:data.length>=17?data[16]*1200:null};
        info.dataBits = {name:"数据位", value:data.length>=18?data[17]&15:null};
        info.stopBits = {name:"停止位", value:data.length>=18?(data[17]&48)>>4:null};
        info.checkBits = {name:"校验位", value:data.length>=18?(data[17]&192)>>6:null};
        info.stats485 = {name:"485始终处于接收状态", value:data.length>=19?data[18]&1:null};
        info.battery = {name:"电池供电", value:data.length>=19?(data[18]&2)>>1:null};
        info.uart1 = {name:"使用Uart1", value:data.length>=19?(data[18]&4)>>2:null};
        info.readTimeout = {name:"读取超时", value:data.length>=19?(data[18]&112)>>4:null};
        info.uploadMode = {name:"上传模式", value:data.length>=19?data[19]:null};
        info.confirmDuty = {name:"confirmDuty", value:data.length>=20?data[19]:null};
        info.transformPort = {name:"透传端口", value:data.length>=22?data[21]:null};
        info.autoResetInterval = {name:"自动复位时间(单位:小时)", value:data.length>=24?data[23]*256+data[22]:null};
        //原始数据data
        info.data = {name:"data", value: up_data};
        result.info = JSON.stringify(info);
        return result;
    };

    var change214 = function (data) {
        var result = {};
        //data内容, data索引4-11对应fuota的索引8-15
        //0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
        //2f 1a 00 18 81 02 13 0c 16 00 02 40 00 00 00 00 08 18 28 28 47 33 d0 02 00 00 00 00
        var tmp = 0;
        //Fuota版本号
        result.fuotaVersion = data[4] & 15;
        tmp = data[4]>>4;
        //>>0操作只是为了去掉整数小数点后面的0
        //硬件类型
        result.hardwareType = tmp + data[5]*16;
        //硬件版本号
        result.hardwareVersion = data[6] >> 4;
        //硬件版本号
        result.softwareVersion = data[7];
        //设备类型
        result.deviceType = data[8] + data[9]*256;
        //业务参数版本号
        result.bizParamVersion = data[10];
        result.info = "{}";
        return result;
    };

    var res = {code:0};
    var data = [];
    for(var i=0;i<up_data.length/2;i++){
        data.push(parseInt(up_data.substr(i*2,2), 16));
    }

    if(fport == 201){
        var arrPacket1 = packet1.split(" ").map(function (a) {
            return parseInt(a, 16);
        });
        //判断升级是否成功
        if(data[7]==0 && data[14] == arrPacket1[13]){
            res.code = 1;
        }else {
            res.code = 0;
        }

        res.result = change201(data);
    }else if(fport == 214){
        res.code = 1;
        res.result = change214(data);
    }

    return res;
};

2、节点任务状态机

状态表
状态值 名称 含义
10 升级中
UPGRADING
至少已发送了一个包,最后一个包还未发送。
20 待升级
READY
刚创建的任务,或将未成功、终止、失败的任务重置为待升级。
30 未成功
UNSUCCESSFUL
升级检查结果为不成功,重试次数未用完。
40 已发完
SENT
一个节点的所有包已发送完毕,等待查询升级结果。
50 成功
SUCCESSFUL
检查升级结果成功。升级结束。
60 终止
STOPPED
升级任务终止。升级结束。
70 失败
FAILED
升级检查升级结果不成功,重试次数已用完。升级结束。
状态机

节点任务状态机

3、FUOTA升级流程

FUOTA流程图

results matching ""

    No results matching ""