Skip to content

协议解析开发

开发流程概述

开发步骤

  • 1.登录协议管理后台
  • 2.创建协议、填入相关标识信息
  • 3.对着文档嘎嘎写、调试运行
  • 4.部署上线

打开http://${host}:{port}/magic/debug/index.html 账号密码和平台的一致

1、登录协议控制台

03login

2、创建协议

03debugindex

3、编写与调试

开发环境

平台支持JavaScript(ES5)jar(打包上传)内置编辑器,推荐使用内置编辑器,安全可控扩展性强

  • 脚本写好了,如下
JavaScript
import log;

// 16进制转10进制数字
var hexToInt = hex => {
  return Integer.parseInt(hex, 16);
};
// 预解码,解析上报的设备编号 deviceId
var preDecode = payload => {
    var result = {}
    var payloadHex = payload.toUpperCase() // 转为大写
    // 校验报文长度和帧头
    if (payloadHex.length() >= 18 && payloadHex.substring(0, 4) === "A5A5") {
        // 从第5位开始取4字节(8个字符)作为 deviceId
        result.deviceId = payloadHex.substring(4, 12)
    }
    return result
}

var decode =(payload,context) => {
  log.info("进入编解码,payload={},context={}",payload,context)
  var result = [];
  var payloadHex =payload.toUpperCase();
  var propertiesObj = { "messageType": "PROPERTIES", "properties": {} };
  var eventObj = { "messageType": "EVENT", "event": "", "data": {} };

  // 验证帧头帧尾
  if (payloadHex.substring(0, 4) != "A5A5" || payloadHex.substring(payloadHex.length() - 4) != "5A5A") {
    return jsonToStr([{ "error": "无效帧格式" }]);
  }

  // 提取核心字段
  var deviceId = payloadHex.substring(4, 8); // 设备ID(4字节)
  var cmdCode = payloadHex.substring(8, 10); // 命令码(1字节)
  var dataLen = hexToInt(payloadHex.substring(10, 12)); // 数据长度
  var dataHex = payloadHex.substring(12, 12 + dataLen * 2); // 数据区
  var checksum = payloadHex.substring(12 + dataLen * 2, 14 + dataLen * 2); // 校验和

  // 设备ID存入所有对象
  propertiesObj.deviceId = deviceId;
  eventObj.deviceId = deviceId;
  //验证新内容
  propertiesObj.context=context;
  propertiesObj.tcpEncode = 'HEX';
  propertiesObj.replyPayload = '727270632C676574637371'
  // 1. 属性上报(命令码01)
  if (cmdCode == "01" && dataLen == 7) {
    // 解析开关状态(01=开,00=关)
    propertiesObj.properties.powerState = dataHex.substring(0, 2) == "01" ? "01" : "00";
    // 解析电流(2字节,单位0.01A)
    var currentHex = dataHex.substring(2, 6);
    propertiesObj.properties.current = (hexToInt(currentHex) * 0.01).toFixed(2);
    // 解析电压(2字节,单位0.1V)
    var voltageHex = dataHex.substring(6, 10);
    propertiesObj.properties.voltage = (hexToInt(voltageHex) * 0.1).toFixed(1);
    // 解析功率(2字节,单位1W)
    var powerHex = dataHex.substring(10, 14);
    propertiesObj.properties.power = hexToInt(powerHex).toString();
    // 加入结果集
    result.push(propertiesObj);
  }

  // 2. 事件上报(命令码02)
  if (cmdCode == "02" && dataLen >= 3) {
    // 事件类型(01=过载,02=过压,03=上线,04=下线)
    var eventType = dataHex.substring(0, 2);
    if (eventType == "01") {
      eventObj.event = "overload";
      eventObj.data.overload = hexToInt(dataHex.substring(2, 6)) + "W"; // 过载功率
    }
    if (eventType == "03") {
      eventObj.event = "online";
      eventObj.data.online = "设备上线";
    }
    if (eventType == "04") {
      eventObj.event = "offline";
      eventObj.data.offline = "设备下线";
    }
    result.push(eventObj);
  }

  // 3. 响应报文(命令码04)
  if (cmdCode == "04" && dataLen == 1) {
    var replyObj = {
      "messageType": "REPLY",
      "function": "switch",
      "data": { "result": dataHex == "00" ? "success" : "fail" }
    };
    replyObj.deviceId = deviceId;
    result.push(replyObj);
  }

  return jsonToStr(result);
};

var encode = payload => {
  var obj = toJson(payload);
  var deviceId = obj.data.deviceId; // 设备ID(4位16进制,如"0001")
  var func = obj.function;
  var params = obj.data;

  // 控制开关(function=switch)
  if (func == "switch") {
    var state = params.state; // 目标状态:01=开,00=关
    if (state != "01" && state != "00") {
      return ""; // 无效状态,返回空
    }

    // 数据区:控制类型(01)+目标状态
    var dataHex = "01" + state;
    var dataLen = dataHex.length() / 2; // 数据长度(字节数)
    var cmdCode = "03"; // 控制指令命令码

    // 拼接完整报文(无校验和)
    var frame = "A5A5" +
                deviceId +
                cmdCode +
                Integer.toHexString(dataLen) + // 数据长度(1位16进制)
                dataHex +
                "5A5A";

    return frame.toUpperCase(); // 转为大写16进制
  }

  return ""; // 不支持的指令
};

//预解码,得到deviceId
//return preDecode("A5A5000101070105DC08F004B05A5A")
//属性上报报文
// return decode('A5A5000101070105DC08F004B07A5A5A');

//过载事件报文
// return decode("A5A5000102030104B0F35A5A")


// return encode('{"deviceId": "0001","function": "switch","data": { "state": "01" }}')


// return encode('{"messageType":"FUNCTIONS","function":"switch","data":{"deviceId":"00010107","state":"01"}}')

03write

  • 试一下断点

03db

4、部署上线

  • 部署上线

03copy