#
zzgtfwq
2 天以前 29d5f847ca4d1f084d8170d5bf2235cd6b7dde14
#
9个文件已修改
390 ■■■■ 已修改文件
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/cache/RgvStatusCache.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/RgvModeType.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/RgvStatusType.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/TaskProtocol.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/RgvThread.java 94 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/SiemensDevpThread.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/console.map.js 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -1204,7 +1204,7 @@
                        crnCommand.setAckFinish((short) 0);  // 任务完成确认位
                        crnCommand.setTaskMode(CrnTaskModeType.GO_ORIGIN); // 任务模式:  站位移转4
                        Integer crnNo = crnProtocol.getCrnNo();
                        int row1 = crnNo * 4;
                        int row1 = crnNo * 4-1;
                        if (crnNo>2){
                            row1 = row1-2;
                        }
src/main/java/com/zy/core/cache/RgvStatusCache.java
@@ -16,7 +16,7 @@
     */
    public static void updateRgvStatus(RgvProtocol status) {
        try {
            if (status.getRgvNo()!=1 && status.getRgvNo() != 2){
            if (status.getRgvNo()!=1 && status.getRgvNo() != 2 && status.getRgvNo() != 3 && status.getRgvNo() != 4){
                return;
            }
            cache.put(status.getRgvNo(), status);
src/main/java/com/zy/core/enums/RgvModeType.java
@@ -3,10 +3,11 @@
public enum RgvModeType {
    NONE(-1, "离线","ffffff"),
    STOP(2, "维修","ffffff"),
    HAND(0, "手动","ffffff"),
    HALF_AUTO(3, "半自动","ffffff"),
    AUTO(1, "自动","ffffff"),
//    STOP(0, "维修","ffffff"),
    STOP(0, "无","ffffff"),
    HAND(1, "手动","ffffff"),
    HALF_AUTO(2, "半自动","ffffff"),
    AUTO(3, "自动","ffffff"),
    OTHER(100, "其它","ffffff"),
    ;
src/main/java/com/zy/core/enums/RgvStatusType.java
@@ -3,10 +3,10 @@
public enum RgvStatusType {
    NONE(-1, "离线","ffffff"),
    NONE0(0, "离线","ffffff"),
    IDLE(1, "空闲","ffffff"),
    WORKING(2, "作业中","ffffff"),// 1:行走  2:取  3:放
    SOS(3, "报警","ffffff"),
//    NONE0(0, "离线","ffffff"),
    IDLE(0, "空闲","ffffff"),
//    WORKING(2, "作业中","ffffff"),// 1:行走  2:取  3:放
//    SOS(3, "报警","ffffff"),
    FETCHING(11, "取货中","ffffff"),
    PUTTING(12, "放货中","ffffff"),
    WAITING(90, "任务完成等待WCS确认","ffffff"),
src/main/java/com/zy/core/model/protocol/TaskProtocol.java
@@ -11,11 +11,12 @@
    private volatile Long taskNo; // 任务号(主属性)
    private volatile Long targetPosition = 0L; // 目标位置
    private volatile Integer targetPositionStaNo = 0; // 目标位置
    private volatile Integer targetPositionStaNoEnd = 0; // 最终目标位置
    private volatile Integer targetPositionStaNoPlcId = 1; // 目标位置
    private volatile int isRunning = 0; // 运行状态  0:初始  1:等待执行  2:执行中 3:执行中断 4:完结
    private volatile int taskStatus = 0; //作业模式  1:行走  2:取  3:放  0:无
    private volatile int taskStatus = 0; //作业模式  1:行走  2:取  3:放  0:无  //zzgt 1:取  2:放  3:库位转移 4:行走
    private volatile boolean direction; // 执行方向(面朝轨道 定位值左小右大)  true:左   false:右  执行方向(面朝轨道  1:自己  2 轨道   true:自己   false:轨道
@@ -58,4 +59,16 @@
        }
        return taskNo+"_"+taskStatusStr;
    }
    public int getTaskStatus$() {
        switch (taskStatus){
            case 1:
                return 4;
            case 2:
                return 1;
            case 3:
                return 2;
        }
        return taskStatus;
    }
}
src/main/java/com/zy/core/thread/RgvThread.java
@@ -169,18 +169,20 @@
                    }
                    continue;
                }
                if (delRgvTask){
                    writeDelRgvTask();
                    delRgvTask = false;
                    continue;
                }
//                if (delRgvTask){
//                    writeDelRgvTask();
//                    delRgvTask = false;
//                    continue;
//                }
                Thread.sleep(50L);
                OperateResultExOne<byte[]> result = siemensNet.Read("DB100.12", (short) 1);
                boolean[] status = siemensNet.getByteTransform().TransBool(result.Content, 0, 1);
                if (status[0]){
                    Thread.sleep(500L);
                    OperateResult result4 = siemensNet.Write("DB100.12.0", false);
                // 构建设备状态对象
                RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId());
                if (rgvProtocol == null) {
                    rgvProtocol = new RgvProtocol();
                }
                if (rgvProtocol.getStatusType().equals(RgvStatusType.WAITING)){
                    OperateResult result4 = siemensNet.Write("DB100.0", (short) 1);
                }
            } catch (Exception e) {
                log.error("RGV数据任务下发复位线程异常!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
@@ -666,7 +668,7 @@
                    RgvTaskCache.updateRgvStatus(rgvTaskProtocolOther);
                    return false;
                }
            } else if (rgvProtocolOther.getStatusType().equals(RgvStatusType.WORKING)) {
            } else if (!rgvProtocolOther.getStatusType().equals(RgvStatusType.IDLE)) {
                if ((rgvProtocolOther.getRgvPosDestination() - rgvProtocolOther.getCarBodyJiaoMing())
                        - (targetPosition + rgvProtocol.getCarBodyKunPeng())
                        > avoidDistance - 50) {//无需避让
@@ -874,7 +876,7 @@
                    return false;
                }
            } else if (rgvProtocolOther.getStatusType().equals(RgvStatusType.WORKING)) {
            } else if (!rgvProtocolOther.getStatusType().equals(RgvStatusType.IDLE)) {
                if ((targetPosition - rgvProtocol.getCarBodyJiaoMing())
                        - (rgvProtocolOther.getRgvPosDestination() + rgvProtocolOther.getCarBodyKunPeng())
                        > avoidDistance-50) {//无需避让
@@ -1010,7 +1012,8 @@
     */
    private void readStatus() {
        try {
            OperateResultExOne<byte[]> result = siemensNet.Read("DB101.0", (short) 20);
            OperateResultExOne<byte[]> result = siemensNet.Read("DB101.0", (short) 36);
            OperateResultExOne<byte[]> result100 = siemensNet.Read("DB100.0", (short) 18);
            if (result.IsSuccess) {
                // 构建设备状态对象
                RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId());
@@ -1021,14 +1024,16 @@
                rgvProtocol.setCarBodyJiaoMing(slave.getCarBodyJiaoMing());
                rgvProtocol.setCarBodyKunPeng(slave.getCarBodyKunPeng());
                rgvProtocol.setRgvPos((long)siemensNet.getByteTransform().TransInt32(result.Content, 0));
                rgvProtocol.setRgvPosDestination((long)siemensNet.getByteTransform().TransInt32(result.Content, 4));
                rgvProtocol.setMode(siemensNet.getByteTransform().TransInt16(result.Content, 0));
//                rgvProtocol.setStatus(siemensNet.getByteTransform().TransInt16(result.Content, 2));
                rgvProtocol.setTaskNo((long)siemensNet.getByteTransform().TransInt32(result.Content, 4));
                rgvProtocol.setStatus(siemensNet.getByteTransform().TransInt16(result.Content, 8));
                rgvProtocol.setLoaded(siemensNet.getByteTransform().TransInt16(result.Content, 10));
                rgvProtocol.setRgvPos((long)siemensNet.getByteTransform().TransInt32(result.Content, 32));
                rgvProtocol.setRgvPosDestination((long)siemensNet.getByteTransform().TransInt32(result100.Content, 14));
                if (rgvProtocol.getRgvPosDestination()==0L){
                    rgvProtocol.setRgvPosDestination(rgvProtocol.getRgvPos());
                }
                rgvProtocol.setStatus(siemensNet.getByteTransform().TransInt16(result.Content, 8));
//                rgvProtocol.setStatus((short)1);
                //作业启动中  解决任务下发后小车状态未更新,小车状态不及时
                if (this.wrkSign == 1 && rgvProtocol.getStatus()!=(short)1){
@@ -1038,26 +1043,22 @@
                    rgvProtocol.setStatus((short)110);
                }
                rgvProtocol.setTaskNo((long)siemensNet.getByteTransform().TransInt32(result.Content, 10));
                rgvProtocol.setRgvNo((int)siemensNet.getByteTransform().TransInt16(result.Content, 14));
                rgvProtocol.setMode(siemensNet.getByteTransform().TransInt16(result.Content, 16));
//                rgvProtocol.setAlarm(siemensNet.getByteTransform().TransInt16(result.Content, 20));
//                rgvProtocol.setxSpeed(siemensNet.getByteTransform().TransInt16(result.Content, 28));
//                rgvProtocol.setxDistance(siemensNet.getByteTransform().TransInt16(result.Content, 40));
//                rgvProtocol.setxDuration(siemensNet.getByteTransform().TransInt16(result.Content, 48));
                rgvProtocol.setAlarm(siemensNet.getByteTransform().TransInt16(result.Content, 16));
//                OperateResultExOne<byte[]> result11 = siemensNet.Read("DB100.12", (short) 1);
                boolean[] status = siemensNet.getByteTransform().TransBool(result.Content, 18, 2);
                rgvProtocol.setLoaded(status[0]? (short)1:(short)0);
                rgvProtocol.setErr1(status[8]);
                rgvProtocol.setErr2(status[9]);
                rgvProtocol.setErr3(status[10]);
                rgvProtocol.setErr4(status[11]);
                rgvProtocol.setErr5(status[12]);
                rgvProtocol.setErr6(status[13]);
                rgvProtocol.setErr7(status[14]);
                rgvProtocol.setErr8(status[15]);
//                boolean[] status = siemensNet.getByteTransform().TransBool(result.Content, 18, 2);
//                rgvProtocol.setLoaded(status[0]? (short)1:(short)0);
//                rgvProtocol.setErr1(status[8]);
//                rgvProtocol.setErr2(status[9]);
//                rgvProtocol.setErr3(status[10]);
//                rgvProtocol.setErr4(status[11]);
//                rgvProtocol.setErr5(status[12]);
//                rgvProtocol.setErr6(status[13]);
//                rgvProtocol.setErr7(status[14]);
//                rgvProtocol.setErr8(status[15]);
//                System.out.println("读线程"+ slave.getId()+"---"+JSON.toJSONString(rgvProtocol));
//                System.out.println("读线程,小车号"+ slave.getId()+"时间戳:"+System.currentTimeMillis()+"小车数据:"+JSON.toJSONString(rgvProtocol));
                OutputQueue.RGV.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功", DateUtils.convert(new Date()), slave.getId()));
@@ -1072,9 +1073,9 @@
//                        }
//                    }
//                }
                if (rgvProtocol.getAlarm$()!=0){
                    RgvErrCache.updateRgvErr(slave.getId(),rgvProtocol.getAlarmM());
                }
//                if (rgvProtocol.getAlarm$()!=0){
//                    RgvErrCache.updateRgvErr(slave.getId(),rgvProtocol.getAlarmM());
//                }
                try {
                    // 根据实时信息更新数据库
@@ -1152,21 +1153,26 @@
//        convertRow(command);
//        taskProtocol.setRgvNo(slave.getId());
//        Long[] array = new Long[11];
        OperateResult result41 = siemensNet.Write("DB100.12.0", false);
        OperateResult result41 = siemensNet.Write("DB100.0", (short) 0);
//        array[0] = taskProtocol.getAckFinish1();
//        array[1] = taskProtocol.getTaskNo();
//        array[2] = taskProtocol.getTaskMode();
//        array[4] = command.getDestinationStaNo();
//        array[10] = taskProtocol.getCommand();
        int taskStatus = taskProtocol.getTaskStatus();
        int taskStatus = taskProtocol.getTaskStatus$();
        int targetPositionStaNo = taskProtocol.getTargetPositionStaNo();
        int targetPositionStaNoEnd = taskProtocol.getTargetPositionStaNoEnd();
        OperateResult result = siemensNet.Write("DB100.0", taskProtocol.getTargetPosition().intValue());
        OperateResult result1 = siemensNet.Write("DB100.4", (short) taskStatus);
        OperateResult result2 = siemensNet.Write("DB100.6", taskProtocol.getTaskNo().intValue());
        OperateResult result3 = siemensNet.Write("DB100.10", taskProtocol.isDirection()? (short) 1 :  (short) 2); // 执行方向(面朝轨道 定位值左小右大)    true:左   false:右
        Thread.sleep(20L);
        OperateResult result2 = siemensNet.Write("DB100.2", taskProtocol.getTaskNo().intValue());
        OperateResult result1 = siemensNet.Write("DB100.6", (short) taskStatus);
        OperateResult result11 = siemensNet.Write("DB100.8", (short) targetPositionStaNo);
        OperateResult result12 = siemensNet.Write("DB100.10", (short) targetPositionStaNo);
        OperateResult result = siemensNet.Write("DB100.14", taskProtocol.getTargetPosition().intValue());
        OperateResult result13 = siemensNet.Write("DB100.18", (short) targetPositionStaNoEnd);
//        OperateResult result3 = siemensNet.Write("DB100.10", taskProtocol.isDirection()? (short) 1 :  (short) 2); // 执行方向(面朝轨道 定位值左小右大)    true:左   false:右
        Thread.sleep(10L);
        OperateResult result4 = siemensNet.Write("DB100.12.0", true);
        OperateResult result4 = siemensNet.Write("DB100.12", (short) 1);
        this.wrkSign = 1;
//        log.info("任务下发线程,小车号"+ slave.getId()+"时间戳:"+System.currentTimeMillis());
src/main/java/com/zy/core/thread/SiemensDevpThread.java
@@ -461,11 +461,11 @@
        //任务下发成功标识
        boolean writeFlag = false;
        while(writeCount < 5){
            OperateResult writeResult1 = siemensS7Net.Write("DB101." + index*8, staProtocol.getWorkNo());    // 工作号
            OperateResult writeResult2 = siemensS7Net.Write("DB101." + (index*8+4), staProtocol.getStaNo().shortValue());    // 目标站
            OperateResult writeResult1 = siemensS7Net.Write("DB100." + index*6, staProtocol.getWorkNo());    // 工作号
            OperateResult writeResult2 = siemensS7Net.Write("DB100." + (index*6+4), staProtocol.getStaNo().shortValue());    // 目标站
            if(writeResult1.IsSuccess && writeResult2.IsSuccess){
                Thread.sleep(200);
                OperateResultExOne<byte[]> readResult = siemensS7Net.Read("DB101.0" + index*8, (short)4);
                OperateResultExOne<byte[]> readResult = siemensS7Net.Read("DB100.0" + index*6, (short)4);
                if(readResult.IsSuccess){
                    Integer workNo = siemensS7Net.getByteTransform().TransInt32(readResult.Content, 0);
src/main/resources/application.yml
@@ -229,10 +229,114 @@
      bay: 52
      lev: 2
  # RGV穿梭车1
  rgv[0]:
    id: 1
    ip: 10.10.10.176
    port: 102
    rack: 0
    slot: 0
    otherId: 2
    carBodyJiaoMing: 13500
    carBodyKunPeng: 2800
    #RGV源站点
    rgvInSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 117
      #执行方向(面朝轨道 定位值左小右大===>  后  前true后false)  true:左   false:右
      direction: false
      staNoOther: 117
      directionOther: false
    rgvInSta[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 120
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 120
      directionOther: false
    rgvInSta[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 123
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 123
      directionOther: false
    rgvInSta[3]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 104
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 104
      directionOther: false
    rgvInSta[4]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 108
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 108
      directionOther: false
    rgvInSta[5]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 112
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 112
      directionOther: false
    rgvInSta[6]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 114
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 114
      directionOther: false
    #RGV目标站点
    rgvOutSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 117
      direction: false
      staNoOther: 117
      directionOther: false
    rgvOutSta[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 120
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 120
      directionOther: false
    rgvOutSta[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 123
      direction: false
      staNoOther: 123
      directionOther: false
    rgvOutSta[3]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 116
      direction: true
      staNoOther: 116
      directionOther: false
    rgvOutSta[4]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 106
      direction: true
      staNoOther: 106
      directionOther: false
    rgvOutSta[5]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 110
      direction: true
      staNoOther: 110
      directionOther: false
    rgvSuperSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 116
      direction: true
      staNoOther: 116
      directionOther: false
  # RGV穿梭车2
  rgv[1]:
    id: 2
    ip: 10.10.10.176
    port: 502
    ip: 10.10.10.178
    port: 102
    rack: 0
    slot: 0
    otherId: 1
@@ -332,14 +436,118 @@
      direction: true
      staNoOther: 102
      directionOther: false
  # RGV穿梭车2
  rgv[0]:
    id: 1
    ip: 10.10.10.178
    port: 502
  # RGV穿梭车3
  rgv[2]:
    id: 3
    ip: 10.10.10.188
    port: 102
    rack: 0
    slot: 0
    otherId: 2
    otherId: 4
    carBodyJiaoMing: 13500
    carBodyKunPeng: 2800
    #RGV源站点
    rgvInSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 117
      #执行方向(面朝轨道 定位值左小右大===>  后  前true后false)  true:左   false:右
      direction: false
      staNoOther: 117
      directionOther: false
    rgvInSta[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 120
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 120
      directionOther: false
    rgvInSta[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 123
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 123
      directionOther: false
    rgvInSta[3]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 104
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 104
      directionOther: false
    rgvInSta[4]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 108
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 108
      directionOther: false
    rgvInSta[5]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 112
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 112
      directionOther: false
    rgvInSta[6]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 114
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 114
      directionOther: false
    #RGV目标站点
    rgvOutSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 117
      direction: false
      staNoOther: 117
      directionOther: false
    rgvOutSta[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 120
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 120
      directionOther: false
    rgvOutSta[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 123
      direction: false
      staNoOther: 123
      directionOther: false
    rgvOutSta[3]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 102
      direction: true
      staNoOther: 102
      directionOther: false
    rgvOutSta[4]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 106
      direction: true
      staNoOther: 106
      directionOther: false
    rgvOutSta[5]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 110
      direction: true
      staNoOther: 110
      directionOther: false
    rgvSuperSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 102
      direction: true
      staNoOther: 102
      directionOther: false
  # RGV穿梭车4
  rgv[3]:
    id: 4
    ip: 10.10.10.190
    port: 102
    rack: 0
    slot: 0
    otherId: 3
    carBodyJiaoMing: 13500
    carBodyKunPeng: 2800
    #RGV源站点
src/main/webapp/static/js/console.map.js
@@ -3,7 +3,7 @@
    "rackCount": 4,
    "crnCount": 3,
    "stbCount": 13,
    "hpPosition": 0,
    "hpPosition": 1,
    "minBayNo": 1,
    "floors": 1,
    "racks": [
@@ -15,7 +15,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        },
        {
            "type": "rack",
@@ -25,7 +25,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        },
        {
            "type": "rack",
@@ -35,7 +35,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        },
        {
            "type": "rack",
@@ -45,7 +45,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        },{
        "type": "rack",
        "id": "rack5",
@@ -54,7 +54,7 @@
        "width": 750,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 52
            "maxBayNo": 64
        }, {
            "type": "rack",
            "id": "rack6",
@@ -63,7 +63,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        }, {
            "type": "rack",
            "id": "rack7",
@@ -72,7 +72,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        }, {
            "type": "rack",
            "id": "rack8",
@@ -81,7 +81,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        }, {
            "type": "rack",
            "id": "rack10",
@@ -90,7 +90,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        }, {
            "type": "rack",
            "id": "rack11",
@@ -99,7 +99,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        }, {
            "type": "rack",
            "id": "rack13",
@@ -108,7 +108,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        }, {
            "type": "rack",
            "id": "rack14",
@@ -117,7 +117,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        }, {
            "type": "rack",
            "id": "rack15",
@@ -126,7 +126,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        }, {
            "type": "rack",
            "id": "rack16",
@@ -135,7 +135,7 @@
            "width": 750,
            "height": 22,
            "minBayNo": 2,
            "maxBayNo": 52
            "maxBayNo": 64
        }
    ],
    "rackDescs": [{