| | |
| | | |
| | | new Thread(() -> { |
| | | try { |
| | | WcsDiagnosisRequest request = aiUtils.makeAiRequest(1000, "系统当前不执行任务,但具体原因不明,请根据以下信息帮助判断。\n\n"); |
| | | WcsDiagnosisRequest request = aiUtils.makeAiRequest(1000, "对当前系统进行巡检,如果有异常情况就进行详细的分析,如果没有异常情况则当成一次检查\n\n"); |
| | | wcsDiagnosisService.diagnoseStream(request, emitter); |
| | | } catch (Exception e) { |
| | | emitter.completeWithError(e); |
| | |
| | | package com.zy.asrs.controller; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.mapper.Wrapper; |
| | |
| | | |
| | | @RequestMapping(value = "/basDualCrnp/delete/auth") |
| | | @ManagerAuth |
| | | public R delete(@RequestParam(value="ids[]") Long[] ids){ |
| | | for (Long id : ids){ |
| | | public R delete(@RequestParam(value="ids[]") Integer[] ids){ |
| | | for (Integer id : ids){ |
| | | basDualCrnpService.deleteById(id); |
| | | } |
| | | return R.ok(); |
| | |
| | | |
| | | @RequestMapping(value = "/basDualCrnpErr/delete/auth") |
| | | @ManagerAuth |
| | | public R delete(@RequestParam(value="ids[]") Long[] ids){ |
| | | for (Long id : ids){ |
| | | public R delete(@RequestParam(value="ids[]") Integer[] ids){ |
| | | for (Integer id : ids){ |
| | | basDualCrnpErrService.deleteById(id); |
| | | } |
| | | return R.ok(); |
| | |
| | | |
| | | @RequestMapping(value = "/basDualCrnpErrLog/delete/auth") |
| | | @ManagerAuth |
| | | public R delete(@RequestParam(value="ids[]") Long[] ids){ |
| | | for (Long id : ids){ |
| | | public R delete(@RequestParam(value="ids[]") Integer[] ids){ |
| | | for (Integer id : ids){ |
| | | basDualCrnpErrLogService.deleteById(id); |
| | | } |
| | | return R.ok(); |
| | |
| | | |
| | | @RequestMapping(value = "/basDualCrnpOpt/delete/auth") |
| | | @ManagerAuth |
| | | public R delete(@RequestParam(value="ids[]") Long[] ids){ |
| | | for (Long id : ids){ |
| | | public R delete(@RequestParam(value="ids[]") Integer[] ids){ |
| | | for (Integer id : ids){ |
| | | basDualCrnpOptService.deleteById(id); |
| | | } |
| | | return R.ok(); |
| | |
| | | }else if (nodeType.equals("RGB(255,192,0)")) { |
| | | //堆垛机 |
| | | nodeData.put("type", "crn"); |
| | | }else if (nodeType.equals("RGB(255,255,0)")) { |
| | | //双工位堆垛机 |
| | | nodeData.put("type", "dualCrn"); |
| | | }else if (nodeType.equals("RGB(0,112,192)")) { |
| | | //输送线 |
| | | nodeData.put("type", "devp"); |
| | |
| | | import com.zy.common.CodeRes; |
| | | import com.zy.common.utils.RedisUtil; |
| | | import com.zy.core.cache.SlaveConnection; |
| | | import com.zy.core.enums.CrnModeType; |
| | | import com.zy.core.enums.RedisKeyType; |
| | | import com.zy.core.enums.RgvStatusType; |
| | | import com.zy.core.enums.SlaveType; |
| | | import com.zy.core.enums.WrkIoType; |
| | | import com.zy.core.enums.*; |
| | | import com.zy.core.model.protocol.CrnProtocol; |
| | | import com.zy.core.model.protocol.DualCrnProtocol; |
| | | import com.zy.core.model.protocol.StationProtocol; |
| | | import com.zy.core.properties.SystemProperties; |
| | | import com.zy.core.thread.CrnThread; |
| | | import com.zy.core.thread.DualCrnThread; |
| | | import com.zy.core.thread.StationThread; |
| | | import com.zy.core.thread.RgvThread; |
| | | import com.zy.core.model.protocol.RgvProtocol; |
| | |
| | | return R.ok().add(vos); |
| | | } |
| | | |
| | | @PostMapping("/latest/data/dualcrn") |
| | | @ManagerAuth(memo = "双工位堆垛机实时数据") |
| | | public R dualCrnLatestData() { |
| | | List<CrnLatestDataVo> vos = new ArrayList<>(); |
| | | List<DeviceConfig> dualCrnList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>() |
| | | .eq("device_type", String.valueOf(SlaveType.DualCrn))); |
| | | for (DeviceConfig deviceConfig : dualCrnList) { |
| | | DualCrnThread crnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, deviceConfig.getDeviceNo()); |
| | | if (crnThread == null) { continue; } |
| | | DualCrnProtocol p = crnThread.getStatus(); |
| | | if (p == null) { continue; } |
| | | CrnLatestDataVo vo = new CrnLatestDataVo(); |
| | | vo.setCrnId(p.getCrnNo()); |
| | | Integer bay = p.getBay() != null ? p.getBay() : p.getBayTwo(); |
| | | vo.setOffset(bay == null ? 0.0 : Double.valueOf(bay)); |
| | | vo.setBay(bay); |
| | | Integer taskNo = (p.getTaskNo() != null && p.getTaskNo() > 0) ? p.getTaskNo() |
| | | : ((p.getTaskNoTwo() != null && p.getTaskNoTwo() > 0) ? p.getTaskNoTwo() : 0); |
| | | vo.setTaskNo(taskNo); |
| | | if (p.getAlarm() != null && p.getAlarm() > 0) { |
| | | vo.setCrnStatus(CrnStatusType.MACHINE_ERROR); |
| | | } else { |
| | | if (taskNo != null && taskNo > 0) { |
| | | vo.setCrnStatus(p.getModeType() == DualCrnModeType.AUTO ? CrnStatusType.MACHINE_AUTO : CrnStatusType.MACHINE_UN_AUTO); |
| | | } else { |
| | | vo.setCrnStatus(p.getModeType() == DualCrnModeType.AUTO ? CrnStatusType.MACHINE_AUTO : CrnStatusType.MACHINE_UN_AUTO); |
| | | } |
| | | } |
| | | vos.add(vo); |
| | | } |
| | | return R.ok().add(vos); |
| | | } |
| | | |
| | | @PostMapping("/latest/data/rgv") |
| | | @ManagerAuth(memo = "RGV实时数据") |
| | | public R rgvLatestData(){ |
| New file |
| | |
| | | package com.zy.asrs.controller; |
| | | |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.core.annotations.ManagerAuth; |
| | | import com.core.common.Cools; |
| | | import com.core.common.R; |
| | | import com.zy.asrs.domain.param.DualCrnCommandParam; |
| | | import com.zy.asrs.domain.vo.DualCrnStateTableVo; |
| | | import com.zy.asrs.entity.BasDualCrnp; |
| | | import com.zy.asrs.service.BasDualCrnpService; |
| | | import com.zy.core.cache.MessageQueue; |
| | | import com.zy.core.cache.SlaveConnection; |
| | | import com.zy.core.enums.SlaveType; |
| | | import com.zy.core.model.Task; |
| | | import com.zy.core.model.command.DualCrnCommand; |
| | | import com.zy.core.model.protocol.DualCrnProtocol; |
| | | import com.zy.core.thread.DualCrnThread; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | @Slf4j |
| | | @RestController |
| | | public class DualCrnController { |
| | | |
| | | @Autowired |
| | | private BasDualCrnpService basDualCrnpService; |
| | | |
| | | @PostMapping("/dualcrn/table/crn/state") |
| | | @ManagerAuth(memo = "双工位堆垛机信息表") |
| | | public R dualCrnStateTable() { |
| | | List<DualCrnStateTableVo> list = new ArrayList<>(); |
| | | List<BasDualCrnp> crnps = basDualCrnpService.selectList(new EntityWrapper<BasDualCrnp>().orderBy("crn_no")); |
| | | for (BasDualCrnp basDualCrnp : crnps) { |
| | | DualCrnStateTableVo vo = new DualCrnStateTableVo(); |
| | | vo.setCrnNo(basDualCrnp.getCrnNo()); |
| | | list.add(vo); |
| | | DualCrnThread crnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, basDualCrnp.getCrnNo()); |
| | | if (crnThread == null) { |
| | | continue; |
| | | } |
| | | DualCrnProtocol p = crnThread.getStatus(); |
| | | if (p == null) { |
| | | continue; |
| | | } |
| | | vo.setTaskNo(p.getTaskNo()); |
| | | vo.setTaskNoTwo(p.getTaskNoTwo()); |
| | | vo.setMode(p.getModeType() == null ? "-" : p.getModeType().desc); |
| | | vo.setStatus(p.getStatusType() == null ? "-" : p.getStatusType().desc); |
| | | vo.setStatusTwo(p.getStatusTypeTwo() == null ? "-" : p.getStatusTypeTwo().desc); |
| | | vo.setLoading(p.getLoaded() != null && p.getLoaded() == 1 ? "有物" : "无物"); |
| | | vo.setLoadingTwo(p.getLoadedTwo() != null && p.getLoadedTwo() == 1 ? "有物" : "无物"); |
| | | vo.setBay(p.getBay()); |
| | | vo.setBayTwo(p.getBayTwo()); |
| | | vo.setLev(p.getLevel()); |
| | | vo.setLevTwo(p.getLevelTwo()); |
| | | vo.setForkOffset(p.getForkPosType() == null ? "-" : p.getForkPosType().desc); |
| | | vo.setForkOffsetTwo(p.getForkPosTypeTwo() == null ? "-" : p.getForkPosTypeTwo().desc); |
| | | vo.setLiftPos(p.getLiftPosType() == null ? "-" : p.getLiftPosType().desc); |
| | | vo.setLiftPosTwo(p.getLiftPosTypeTwo() == null ? "-" : p.getLiftPosTypeTwo().desc); |
| | | vo.setWalkPos(p.getWalkPos() != null && p.getWalkPos() == 0 ? "在定位" : "不在定位"); |
| | | vo.setWalkPosTwo(p.getWalkPosTwo() != null && p.getWalkPosTwo() == 0 ? "在定位" : "不在定位"); |
| | | vo.setTaskReceive(p.getTaskReceive() != null && p.getTaskReceive() == 1 ? "接收" : "无任务"); |
| | | vo.setTaskReceiveTwo(p.getTaskReceiveTwo() != null && p.getTaskReceiveTwo() == 1 ? "接收" : "无任务"); |
| | | vo.setXspeed(p.getXSpeed()); |
| | | vo.setYspeed(p.getYSpeed()); |
| | | vo.setZspeed(p.getZSpeed()); |
| | | vo.setXdistance(p.getXDistance()); |
| | | vo.setYdistance(p.getYDistance()); |
| | | vo.setXduration(p.getXDuration()); |
| | | vo.setYduration(p.getYDuration()); |
| | | vo.setWarnCode(p.getAlarm() == null ? "-" : String.valueOf(p.getAlarm())); |
| | | if (p.getAlarm() != null && p.getAlarm() > 0) { |
| | | vo.setDeviceStatus("ERROR"); |
| | | } else if (p.getTaskNo() != null && p.getTaskNo() > 0 || p.getTaskNoTwo() != null && p.getTaskNoTwo() > 0) { |
| | | vo.setDeviceStatus("WORKING"); |
| | | } else if (p.getModeType() != null && "AUTO".equals(p.getModeType().name())) { |
| | | vo.setDeviceStatus("AUTO"); |
| | | } else { |
| | | vo.setDeviceStatus("OFFLINE"); |
| | | } |
| | | } |
| | | return R.ok().add(list); |
| | | } |
| | | |
| | | @PostMapping("/dualcrn/command/take") |
| | | @ManagerAuth(memo = "双工位堆垛机取放货命令") |
| | | public R dualCrnCommandTake(@RequestBody DualCrnCommandParam param) { |
| | | if (Cools.isEmpty(param)) { |
| | | return R.error("缺少参数"); |
| | | } |
| | | Integer crnNo = param.getCrnNo(); |
| | | String sourceLocNo = param.getSourceLocNo(); |
| | | String targetLocNo = param.getTargetLocNo(); |
| | | Integer station = param.getStation(); |
| | | DualCrnThread crnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, crnNo); |
| | | if (crnThread == null) { |
| | | return R.error("线程不存在"); |
| | | } |
| | | DualCrnCommand command = crnThread.getPickAndPutCommand(sourceLocNo, targetLocNo, 9999, crnNo, station); |
| | | MessageQueue.offer(SlaveType.DualCrn, crnNo, new Task(2, command)); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @PostMapping("/dualcrn/command/pick") |
| | | @ManagerAuth(memo = "双工位堆垛机取货命令") |
| | | public R dualCrnCommandPick(@RequestBody DualCrnCommandParam param) { |
| | | if (Cools.isEmpty(param)) { |
| | | return R.error("缺少参数"); |
| | | } |
| | | Integer crnNo = param.getCrnNo(); |
| | | String targetLocNo = param.getTargetLocNo(); |
| | | Integer station = param.getStation(); |
| | | DualCrnThread crnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, crnNo); |
| | | if (crnThread == null) { |
| | | return R.error("线程不存在"); |
| | | } |
| | | DualCrnCommand command = crnThread.getPickCommand(targetLocNo, 9999, crnNo, station); |
| | | MessageQueue.offer(SlaveType.DualCrn, crnNo, new Task(2, command)); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @PostMapping("/dualcrn/command/put") |
| | | @ManagerAuth(memo = "双工位堆垛机放货命令") |
| | | public R dualCrnCommandPut(@RequestBody DualCrnCommandParam param) { |
| | | if (Cools.isEmpty(param)) { |
| | | return R.error("缺少参数"); |
| | | } |
| | | Integer crnNo = param.getCrnNo(); |
| | | String targetLocNo = param.getTargetLocNo(); |
| | | Integer station = param.getStation(); |
| | | DualCrnThread crnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, crnNo); |
| | | if (crnThread == null) { |
| | | return R.error("线程不存在"); |
| | | } |
| | | DualCrnCommand command = crnThread.getPutCommand(targetLocNo, 9999, crnNo, station); |
| | | MessageQueue.offer(SlaveType.DualCrn, crnNo, new Task(2, command)); |
| | | return R.ok(); |
| | | } |
| | | |
| | | |
| | | @PostMapping("/dualcrn/command/move") |
| | | @ManagerAuth(memo = "双工位堆垛机移动命令") |
| | | public R dualCrnCommandMove(@RequestBody DualCrnCommandParam param) { |
| | | if (Cools.isEmpty(param)) { |
| | | return R.error("缺少参数"); |
| | | } |
| | | Integer crnNo = param.getCrnNo(); |
| | | String targetLocNo = param.getTargetLocNo(); |
| | | Integer station = param.getStation(); |
| | | DualCrnThread crnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, crnNo); |
| | | if (crnThread == null) { |
| | | return R.error("线程不存在"); |
| | | } |
| | | DualCrnCommand command = crnThread.getMoveCommand(targetLocNo, 9999, crnNo); |
| | | if (station != null) { |
| | | command.setStation(station.shortValue()); |
| | | } |
| | | MessageQueue.offer(SlaveType.DualCrn, crnNo, new Task(2, command)); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @PostMapping("/dualcrn/command/taskComplete") |
| | | @ManagerAuth(memo = "双工位堆垛机任务完成确认") |
| | | public R dualCrnCommandTaskComplete(@RequestBody DualCrnCommandParam param) { |
| | | if (Cools.isEmpty(param)) { |
| | | return R.error("缺少参数"); |
| | | } |
| | | Integer crnNo = param.getCrnNo(); |
| | | Integer station = param.getStation(); |
| | | DualCrnThread crnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, crnNo); |
| | | if (crnThread == null) { |
| | | return R.error("线程不存在"); |
| | | } |
| | | DualCrnCommand command = crnThread.getResetCommand(crnNo, station); |
| | | MessageQueue.offer(SlaveType.DualCrn, crnNo, new Task(2, command)); |
| | | return R.ok(); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.zy.asrs.domain.param; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class DualCrnCommandParam { |
| | | private Integer crnNo; |
| | | private String sourceLocNo; |
| | | private String targetLocNo; |
| | | private Integer station; |
| | | } |
| New file |
| | |
| | | package com.zy.asrs.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class DualCrnStateTableVo { |
| | | |
| | | private Integer crnNo; |
| | | |
| | | private String mode = "-"; |
| | | |
| | | private String warnCode = "-"; |
| | | |
| | | private Integer taskNo = 0; |
| | | |
| | | private Integer taskNoTwo = 0; |
| | | |
| | | private String status = "-"; |
| | | |
| | | private String statusTwo = "-"; |
| | | |
| | | private String loading = "-"; |
| | | |
| | | private String loadingTwo = "-"; |
| | | |
| | | private Integer bay; |
| | | |
| | | private Integer bayTwo; |
| | | |
| | | private Integer lev; |
| | | |
| | | private Integer levTwo; |
| | | |
| | | private String forkOffset = "-"; |
| | | |
| | | private String forkOffsetTwo = "-"; |
| | | |
| | | private String liftPos = "-"; |
| | | |
| | | private String liftPosTwo = "-"; |
| | | |
| | | private String walkPos = "-"; |
| | | |
| | | private String walkPosTwo = "-"; |
| | | |
| | | private String taskReceive = "-"; |
| | | |
| | | private String taskReceiveTwo = "-"; |
| | | |
| | | private Integer xspeed = 0; |
| | | |
| | | private Integer yspeed = 0; |
| | | |
| | | private Integer zspeed = 0; |
| | | |
| | | private Integer xdistance = 0; |
| | | |
| | | private Integer ydistance = 0; |
| | | |
| | | private Integer xduration = 0; |
| | | |
| | | private Integer yduration = 0; |
| | | |
| | | private String deviceStatus = "OFFLINE"; |
| | | } |
| | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | |
| | | } else if ("/console/latest/data/rgv".equals(url)) { |
| | | ConsoleController consoleController = SpringUtils.getBean(ConsoleController.class); |
| | | resObj = consoleController.rgvLatestData(); |
| | | } else if ("/console/latest/data/dualcrn".equals(url)) { |
| | | ConsoleController consoleController = SpringUtils.getBean(ConsoleController.class); |
| | | resObj = consoleController.dualCrnLatestData(); |
| | | } else if ("/crn/table/crn/state".equals(url)) { |
| | | resObj = SpringUtils.getBean(CrnController.class).crnStateTable(); |
| | | } else if ("/rgv/table/rgv/state".equals(url)) { |
| | | resObj = SpringUtils.getBean(RgvController.class).rgvStateTable(); |
| | | } else if ("/dualcrn/table/crn/state".equals(url)) { |
| | | resObj = SpringUtils.getBean(com.zy.asrs.controller.DualCrnController.class).dualCrnStateTable(); |
| | | } |
| | | } catch (Exception e) { |
| | | R err = R.error(e.getMessage()); |
| | |
| | | |
| | | // 堆垛机mq交换机 |
| | | private static final Map<Integer, LinkedBlockingQueue<Task>> CRN_EXCHANGE = new ConcurrentHashMap<>(); |
| | | // 双工位堆垛机mq交换机 |
| | | private static final Map<Integer, LinkedBlockingQueue<Task>> DUAL_CRN_EXCHANGE = new ConcurrentHashMap<>(); |
| | | // 输送线mq交换机 |
| | | private static final Map<Integer, ConcurrentLinkedQueue<Task>> DEVP_EXCHANGE = new ConcurrentHashMap<>(); |
| | | // 条码扫描仪mq交换机 |
| | |
| | | switch (type) { |
| | | case Crn: |
| | | CRN_EXCHANGE.put(id, new LinkedBlockingQueue<>(1)); |
| | | break; |
| | | case DualCrn: |
| | | DUAL_CRN_EXCHANGE.put(id, new LinkedBlockingQueue<>(1)); |
| | | break; |
| | | case Rgv: |
| | | RGV_EXCHANGE.put(id, new LinkedBlockingQueue<>(1)); |
| | |
| | | switch (type) { |
| | | case Crn: |
| | | return CRN_EXCHANGE.get(id).offer(task); |
| | | case DualCrn: |
| | | return DUAL_CRN_EXCHANGE.get(id).offer(task); |
| | | case Rgv: |
| | | return RGV_EXCHANGE.get(id).offer(task); |
| | | case Devp: |
| | |
| | | switch (type) { |
| | | case Crn: |
| | | return CRN_EXCHANGE.get(id).poll(); |
| | | case DualCrn: |
| | | return DUAL_CRN_EXCHANGE.get(id).poll(); |
| | | case Rgv: |
| | | return RGV_EXCHANGE.get(id).poll(); |
| | | case Devp: |
| | |
| | | switch (type) { |
| | | case Crn: |
| | | return CRN_EXCHANGE.get(id).peek(); |
| | | case DualCrn: |
| | | return DUAL_CRN_EXCHANGE.get(id).peek(); |
| | | case Rgv: |
| | | return RGV_EXCHANGE.get(id).peek(); |
| | | case Devp: |
| | |
| | | case Crn: |
| | | CRN_EXCHANGE.get(id).clear(); |
| | | break; |
| | | case DualCrn: |
| | | DUAL_CRN_EXCHANGE.get(id).clear(); |
| | | break; |
| | | case Rgv: |
| | | RGV_EXCHANGE.get(id).clear(); |
| | | break; |
| New file |
| | |
| | | package com.zy.core.enums; |
| | | |
| | | public enum DualCrnForkPosType { |
| | | |
| | | NONE(-1, "不在定位"), // 货叉原位 |
| | | HOME(0, "货叉原位"), // 货叉原位 |
| | | LEFT(1, "货叉在左侧"), // 货叉在左侧 |
| | | RIGHT(2, "货叉在右侧"), // 货叉在右侧 |
| | | _LEFT(3, "货叉在左侧远"), // 货叉在右侧远 |
| | | _RIGHT(4, "货叉在右侧远"), // 货叉在右侧远 |
| | | ; |
| | | |
| | | public Integer id; |
| | | public String desc; |
| | | DualCrnForkPosType(Integer id, String desc) { |
| | | this.id = id; |
| | | this.desc = desc; |
| | | } |
| | | |
| | | public static DualCrnForkPosType get(Integer id) { |
| | | if (null == id) { |
| | | return null; |
| | | } |
| | | for (DualCrnForkPosType type : DualCrnForkPosType.values()) { |
| | | if (type.id.equals(id)) { |
| | | return type; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static DualCrnForkPosType get(DualCrnForkPosType type) { |
| | | if (null == type) { |
| | | return null; |
| | | } |
| | | for (DualCrnForkPosType crnForkPosType : DualCrnForkPosType.values()) { |
| | | if (crnForkPosType == type) { |
| | | return crnForkPosType; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| New file |
| | |
| | | package com.zy.core.enums; |
| | | |
| | | public enum DualCrnLiftPosType { |
| | | |
| | | ERROR(-1, "未知"), // 不在定位 |
| | | NONE(0, "不在定位"), // 不在定位 |
| | | _DOWN(1, "双深低位"), // |
| | | DOWN(2, "单深低位"), // |
| | | _UP(3, "单深高位"), // |
| | | UP(4, "双深高位"), // |
| | | ; |
| | | |
| | | public Integer id; |
| | | public String desc; |
| | | DualCrnLiftPosType(Integer id, String desc) { |
| | | this.id = id; |
| | | this.desc = desc; |
| | | } |
| | | |
| | | public static DualCrnLiftPosType get(Integer id) { |
| | | if (null == id) { |
| | | return null; |
| | | } |
| | | for (DualCrnLiftPosType type : DualCrnLiftPosType.values()) { |
| | | if (type.id.equals(id)) { |
| | | return type; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static DualCrnLiftPosType get(DualCrnLiftPosType type) { |
| | | if (null == type) { |
| | | return null; |
| | | } |
| | | for (DualCrnLiftPosType crnLiftPosType : DualCrnLiftPosType.values()) { |
| | | if (crnLiftPosType == type) { |
| | | return crnLiftPosType; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.zy.core.enums; |
| | | |
| | | public enum DualCrnModeType { |
| | | |
| | | NONE(-1, "离线"), |
| | | STOP(0, "维修"), |
| | | HAND(1, "手动"), |
| | | HALF_AUTO(2, "半自动"), |
| | | AUTO(3, "自动"), |
| | | ; |
| | | |
| | | public Integer id; |
| | | public String desc; |
| | | DualCrnModeType(Integer id, String desc) { |
| | | this.id = id; |
| | | this.desc = desc; |
| | | } |
| | | |
| | | public static DualCrnModeType get(Integer id) { |
| | | if (null == id) { |
| | | return null; |
| | | } |
| | | for (DualCrnModeType type : DualCrnModeType.values()) { |
| | | if (type.id.equals(id)) { |
| | | return type; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static DualCrnModeType get(DualCrnModeType type) { |
| | | if (null == type) { |
| | | return null; |
| | | } |
| | | for (DualCrnModeType crnModeType : DualCrnModeType.values()) { |
| | | if (crnModeType == type) { |
| | | return crnModeType; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| New file |
| | |
| | | package com.zy.core.enums; |
| | | |
| | | public enum DualCrnStatusType { |
| | | |
| | | NONE(-1, "离线"), |
| | | IDLE(0, "空闲"), |
| | | FETCH_MOVING(1, "取货行走"), |
| | | FETCH_WAITING(2, "取货等待"), |
| | | FETCHING(3, "取货中"), |
| | | PUT_MOVING(4, "放货走行"), |
| | | PUT_WAITING(5, "放货等待"), |
| | | PUTTING(6, "放货中"), |
| | | ORIGIN_GO(7, "回原点"), |
| | | ORIGIN_BACK(8, "回反原点"), |
| | | MOVING(9, "走行中"), |
| | | WAITING(90, "任务完成等待WCS确认"), |
| | | PAUSE(11, "任务暂停"), |
| | | SOS(99, "报警"), |
| | | UNKNOW(100, "其他"), |
| | | ; |
| | | |
| | | public Integer id; |
| | | public String desc; |
| | | DualCrnStatusType(Integer id, String desc) { |
| | | this.id = id; |
| | | this.desc = desc; |
| | | } |
| | | |
| | | public static DualCrnStatusType get(Integer id) { |
| | | if (null == id) { |
| | | return null; |
| | | } |
| | | for (DualCrnStatusType type : DualCrnStatusType.values()) { |
| | | if (type.id.equals(id)) { |
| | | return type; |
| | | } |
| | | } |
| | | return NONE; |
| | | } |
| | | |
| | | public static DualCrnStatusType get(DualCrnStatusType type) { |
| | | if (null == type) { |
| | | return null; |
| | | } |
| | | for (DualCrnStatusType crnStatusType : DualCrnStatusType.values()) { |
| | | if (crnStatusType == type) { |
| | | return crnStatusType; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| New file |
| | |
| | | package com.zy.core.enums; |
| | | |
| | | public enum DualCrnTaskModeType { |
| | | |
| | | NONE(0), // 无 |
| | | PICK(1), // 取货 |
| | | PUT(2), // 放货 |
| | | TRANSFER(3), // 取放货 |
| | | MOVE(4), // 移动 |
| | | CONFIRM(5), // 确认 |
| | | ; |
| | | |
| | | public Integer id; |
| | | DualCrnTaskModeType(Integer id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public static DualCrnTaskModeType get(Integer id) { |
| | | if (null == id) { |
| | | return null; |
| | | } |
| | | for (DualCrnTaskModeType type : DualCrnTaskModeType.values()) { |
| | | if (type.id.equals(id)) { |
| | | return type; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static DualCrnTaskModeType get(DualCrnTaskModeType type) { |
| | | if (null == type) { |
| | | return null; |
| | | } |
| | | for (DualCrnTaskModeType crnTaskModeType : DualCrnTaskModeType.values()) { |
| | | if (crnTaskModeType == type) { |
| | | return crnTaskModeType; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | } |
| | |
| | | // 堆垛机号 |
| | | private Integer crnNo = 0; |
| | | |
| | | // 任务完成确认位 |
| | | private Short ackFinish = 0; |
| | | |
| | | // 任务号 |
| | | private Short taskNo = 0; |
| | | |
| | | /** |
| | | * 任务模式: |
| | | * 0 = 无 |
| | | * 1 = 入库 源和目标都发 |
| | | * 2 = 出库 源和目标都发 |
| | | * 3 = 库位移转 源和目标都发 |
| | | * 4 = 站位移转 源和目标都发 |
| | | * 5 = 回原点 不用发 |
| | | * 6 = 去反原点 目标发 |
| | | * 7 = 坐标移行 取货发 |
| | | * 90 = 设置时间 |
| | | * 99 = 取消当前任务 |
| | | */ |
| | | private Short taskMode = 0; |
| | | |
| | |
| | | import com.zy.core.enums.CrnStatusType; |
| | | import lombok.Data; |
| | | |
| | | import java.util.Map; |
| | | |
| | | @Data |
| | | public class CrnProtocol { |
| | | |
| | |
| | | private Integer crnLane = 1; |
| | | |
| | | /** |
| | | * 称重数据 |
| | | */ |
| | | private Double weight; |
| | | |
| | | /** |
| | | * 条码数据 |
| | | */ |
| | | private String barcode; |
| | | |
| | | /** |
| | | * 日志采集时间 |
| | | */ |
| | | private Long deviceDataLog = System.currentTimeMillis(); |
| | |
| | | */ |
| | | private Long lastCommandTime = System.currentTimeMillis(); |
| | | |
| | | /** |
| | | * 扩展数据 |
| | | */ |
| | | private Map<String, Object> extend; |
| | | |
| | | public void setMode(Integer mode) { |
| | | this.mode = mode; |
| | | this.modeType = CrnModeType.get(mode); |
| | |
| | | package com.zy.core.model.protocol; |
| | | |
| | | import com.zy.core.enums.CrnForkPosType; |
| | | import com.zy.core.enums.CrnLiftPosType; |
| | | import com.zy.core.enums.CrnModeType; |
| | | import com.zy.core.enums.CrnStatusType; |
| | | import com.zy.core.enums.DualCrnForkPosType; |
| | | import com.zy.core.enums.DualCrnLiftPosType; |
| | | import com.zy.core.enums.DualCrnModeType; |
| | | import com.zy.core.enums.DualCrnStatusType; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.Map; |
| | | |
| | | @Data |
| | | public class DualCrnProtocol { |
| | |
| | | */ |
| | | public Integer mode; |
| | | |
| | | public CrnModeType modeType; |
| | | public DualCrnModeType modeType; |
| | | |
| | | /** |
| | | * 异常码 |
| | |
| | | /** |
| | | * 工位1状态枚举 |
| | | */ |
| | | public CrnStatusType statusType; |
| | | public DualCrnStatusType statusType; |
| | | |
| | | /** |
| | | * 工位2状态枚举 |
| | | */ |
| | | public CrnStatusType statusTypeTwo; |
| | | public DualCrnStatusType statusTypeTwo; |
| | | |
| | | /** |
| | | * 工位1堆垛机当前列号 |
| | |
| | | */ |
| | | public Integer forkPosTwo; |
| | | |
| | | public CrnForkPosType forkPosType; |
| | | public DualCrnForkPosType forkPosType; |
| | | |
| | | public CrnForkPosType forkPosTypeTwo; |
| | | public DualCrnForkPosType forkPosTypeTwo; |
| | | |
| | | /** |
| | | * 当前载货台位置 |
| | |
| | | |
| | | public Integer liftPosTwo; |
| | | |
| | | public CrnLiftPosType liftPosType; |
| | | public DualCrnLiftPosType liftPosType; |
| | | |
| | | public CrnLiftPosType liftPosTypeTwo; |
| | | public DualCrnLiftPosType liftPosTypeTwo; |
| | | |
| | | /** |
| | | * 走行在定位 |
| | |
| | | public Integer loaded; |
| | | |
| | | public Integer loadedTwo; |
| | | |
| | | /** |
| | | * 任务接收状态 |
| | | * 0 = 未接收 |
| | | * 1 = 已接收 |
| | | */ |
| | | public Integer taskReceive; |
| | | |
| | | public Integer taskReceiveTwo; |
| | | |
| | | private Integer temp1; |
| | | |
| | |
| | | */ |
| | | private Long lastCommandTime = System.currentTimeMillis(); |
| | | |
| | | /** |
| | | * 扩展数据 |
| | | */ |
| | | private Map<String, Object> extend; |
| | | |
| | | public void setMode(Integer mode) { |
| | | this.mode = mode; |
| | | this.modeType = CrnModeType.get(mode); |
| | | this.modeType = DualCrnModeType.get(mode); |
| | | } |
| | | |
| | | public void setMode(CrnModeType type) { |
| | | public void setMode(DualCrnModeType type) { |
| | | this.modeType = type; |
| | | this.mode = CrnModeType.get(type).id; |
| | | this.mode = DualCrnModeType.get(type).id; |
| | | } |
| | | |
| | | public void setForkPos(Integer forkPos) { |
| | | this.forkPos = forkPos; |
| | | this.forkPosType = CrnForkPosType.get(forkPos); |
| | | this.forkPosType = DualCrnForkPosType.get(forkPos); |
| | | } |
| | | |
| | | public void setForkPos(CrnForkPosType type) { |
| | | public void setForkPosTwo(Integer forkPosTwo) { |
| | | this.forkPosTwo = forkPosTwo; |
| | | this.forkPosTypeTwo = DualCrnForkPosType.get(forkPosTwo); |
| | | } |
| | | |
| | | public void setForkPos(DualCrnForkPosType type) { |
| | | this.forkPosType = type; |
| | | this.forkPos = CrnForkPosType.get(type).id; |
| | | this.forkPos = DualCrnForkPosType.get(type).id; |
| | | } |
| | | |
| | | public void setForkPosTwo(DualCrnForkPosType type) { |
| | | this.forkPosTypeTwo = type; |
| | | this.forkPosTwo = DualCrnForkPosType.get(type).id; |
| | | } |
| | | |
| | | public void setLiftPos(Integer liftPos) { |
| | | this.liftPos = liftPos; |
| | | this.liftPosType = CrnLiftPosType.get(liftPos); |
| | | this.liftPosType = DualCrnLiftPosType.get(liftPos); |
| | | } |
| | | |
| | | public void setLiftPos(CrnLiftPosType type) { |
| | | public void setLiftPosTwo(Integer liftPosTwo) { |
| | | this.liftPosTwo = liftPosTwo; |
| | | this.liftPosTypeTwo = DualCrnLiftPosType.get(liftPosTwo); |
| | | } |
| | | |
| | | public void setLiftPos(DualCrnLiftPosType type) { |
| | | this.liftPosType = type; |
| | | this.liftPos = CrnLiftPosType.get(type).id; |
| | | this.liftPos = DualCrnLiftPosType.get(type).id; |
| | | } |
| | | |
| | | public void setLiftPosTwo(DualCrnLiftPosType type) { |
| | | this.liftPosTypeTwo = type; |
| | | this.liftPosTwo = DualCrnLiftPosType.get(type).id; |
| | | } |
| | | |
| | | public void setStatus(Integer status){ |
| | | this.status = status; |
| | | this.statusType = CrnStatusType.get(status); |
| | | this.statusType = DualCrnStatusType.get(status); |
| | | } |
| | | |
| | | public void setStatus(CrnStatusType type){ |
| | | public void setStatus(DualCrnStatusType type){ |
| | | this.statusType = type; |
| | | this.status = CrnStatusType.get(type).id; |
| | | this.status = DualCrnStatusType.get(type).id; |
| | | } |
| | | |
| | | public void setStatusTwo(Integer statusTwo){ |
| | | this.statusTwo = statusTwo; |
| | | this.statusTypeTwo = DualCrnStatusType.get(statusTwo); |
| | | } |
| | | |
| | | public void setStatusTwo(DualCrnStatusType type){ |
| | | this.statusTypeTwo = type; |
| | | this.statusTwo = DualCrnStatusType.get(type).id; |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.Map; |
| | | |
| | | @Data |
| | | public class RgvProtocol { |
| | | |
| | |
| | | private Long deviceDataLog = System.currentTimeMillis(); |
| | | |
| | | private Long lastCommandTime = System.currentTimeMillis(); |
| | | |
| | | /** |
| | | * 扩展数据 |
| | | */ |
| | | private Map<String, Object> extend; |
| | | } |
| | |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.Map; |
| | | |
| | | @Data |
| | | public class StationProtocol { |
| | | |
| | |
| | | //重量 |
| | | private Double weight; |
| | | |
| | | /** |
| | | * 扩展数据 |
| | | */ |
| | | private Map<String, Object> extend; |
| | | |
| | | @Override |
| | | public StationProtocol clone() { |
| | | try { |
| | |
| | | public CommandResponse sendCommand(StationCommand command) { |
| | | return zyStationConnectApi.sendCommand(deviceConfig.getDeviceNo(), command); |
| | | } |
| | | |
| | | public CommandResponse sendOriginCommand(String address, short[] data) { |
| | | return zyStationConnectApi.sendOriginCommand(address, data); |
| | | } |
| | | |
| | | public byte[] readOriginCommand(String address, int length) { |
| | | return zyStationConnectApi.readOriginCommand(address, length); |
| | | } |
| | | } |
| | |
| | | |
| | | CommandResponse sendCommand(Integer deviceNo, StationCommand command);//下发命令 |
| | | |
| | | CommandResponse sendOriginCommand(String address, short[] data);//原始命令 |
| | | |
| | | byte[] readOriginCommand(String address, int length);//读取原始数据 |
| | | } |
| | |
| | | public Integer loadedTwo; |
| | | |
| | | /** |
| | | * 任务接收状态 |
| | | * 0 = 未接收 |
| | | * 1 = 已接收 |
| | | */ |
| | | public Integer taskReceive; |
| | | |
| | | public Integer taskReceiveTwo; |
| | | |
| | | /** |
| | | * X行走线速度m/min |
| | | */ |
| | | private Integer xSpeed; |
| | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.zy.asrs.entity.DeviceConfig; |
| | | import com.zy.core.enums.CrnStatusType; |
| | | import com.zy.core.enums.CrnTaskModeType; |
| | | import com.zy.core.enums.DualCrnTaskModeType; |
| | | import com.zy.core.model.CommandResponse; |
| | | import com.zy.core.model.command.DualCrnCommand; |
| | | import com.zy.core.network.api.ZyDualCrnConnectApi; |
| | |
| | | @Override |
| | | public CommandResponse sendCommand(DualCrnCommand command) { |
| | | CommandResponse response = new CommandResponse(false); |
| | | if (command.getTaskMode().intValue() == CrnTaskModeType.LOC_MOVE.id) { |
| | | if (command.getTaskMode().intValue() == DualCrnTaskModeType.TRANSFER.id) { |
| | | //取放货 |
| | | executor.submit(() -> commandTake(command)); |
| | | } else if (command.getTaskMode().intValue() == CrnTaskModeType.CRN_MOVE.id) { |
| | | } else if (command.getTaskMode().intValue() == DualCrnTaskModeType.PICK.id) { |
| | | //取货 |
| | | executor.submit(() -> commandPick(command)); |
| | | } else if (command.getTaskMode().intValue() == DualCrnTaskModeType.PUT.id) { |
| | | //放货 |
| | | executor.submit(() -> commandPut(command)); |
| | | } else if (command.getTaskMode().intValue() == DualCrnTaskModeType.MOVE.id) { |
| | | //移动 |
| | | executor.submit(() -> commandMove(command)); |
| | | } else if (command.getTaskMode().intValue() == CrnTaskModeType.NONE.id) { |
| | | } else if (command.getTaskMode().intValue() == DualCrnTaskModeType.CONFIRM.id) { |
| | | //复位 |
| | | executor.submit(() -> commandTaskComplete(command)); |
| | | } |
| | |
| | | } |
| | | |
| | | private void commandTaskComplete(DualCrnCommand command) { |
| | | this.crnStatus.setTaskNo(0); |
| | | this.crnStatus.setStatus(CrnStatusType.IDLE.id); |
| | | if(command.getStation() == 1) { |
| | | this.crnStatus.setTaskNo(0); |
| | | this.crnStatus.setTaskReceive(0); |
| | | this.crnStatus.setStatus(CrnStatusType.IDLE.id); |
| | | }else { |
| | | this.crnStatus.setTaskNoTwo(0); |
| | | this.crnStatus.setTaskReceiveTwo(0); |
| | | this.crnStatus.setStatusTwo(CrnStatusType.IDLE.id); |
| | | } |
| | | } |
| | | |
| | | private void commandMove(DualCrnCommand command) { |
| | |
| | | if(command.getStation() == 1) { |
| | | this.crnStatus.setTaskNo(taskNo); |
| | | this.crnStatus.setStatus(CrnStatusType.MOVING.id); |
| | | this.crnStatus.setTaskReceive(1); |
| | | moveY(this.crnStatus.getBay(), destinationPosY, command.getStation().intValue()); |
| | | moveZ(this.crnStatus.getLevel(), destinationPosZ, command.getStation().intValue()); |
| | | this.crnStatus.setStatus(CrnStatusType.WAITING.id); |
| | | }else { |
| | | this.crnStatus.setTaskNoTwo(taskNo); |
| | | this.crnStatus.setStatusTwo(CrnStatusType.MOVING.id); |
| | | this.crnStatus.setTaskReceive(1); |
| | | moveY(this.crnStatus.getBayTwo(), destinationPosY, command.getStation().intValue()); |
| | | moveZ(this.crnStatus.getLevelTwo(), destinationPosZ, command.getStation().intValue()); |
| | | this.crnStatus.setStatusTwo(CrnStatusType.WAITING.id); |
| | |
| | | int taskMode = command.getTaskMode().intValue(); |
| | | int taskNo = command.getTaskNo().intValue(); |
| | | |
| | | this.crnStatus.setMode(taskMode); |
| | | if(command.getStation() == 1) { |
| | | this.crnStatus.setTaskNo(taskNo); |
| | | this.crnStatus.setStatus(CrnStatusType.FETCH_MOVING.id); |
| | | this.crnStatus.setTaskReceive(1); |
| | | |
| | | moveY(this.crnStatus.getBay(), sourcePosY, command.getStation().intValue()); |
| | | moveZ(this.crnStatus.getLevel(), sourcePosZ, command.getStation().intValue()); |
| | |
| | | }else { |
| | | this.crnStatus.setTaskNoTwo(taskNo); |
| | | this.crnStatus.setStatusTwo(CrnStatusType.FETCH_MOVING.id); |
| | | this.crnStatus.setTaskReceiveTwo(1); |
| | | |
| | | moveY(this.crnStatus.getBayTwo(), sourcePosY, command.getStation().intValue()); |
| | | moveZ(this.crnStatus.getLevelTwo(), sourcePosZ, command.getStation().intValue()); |
| | |
| | | } |
| | | } |
| | | |
| | | private void commandPick(DualCrnCommand command) { |
| | | int destinationPosX = command.getDestinationPosX().intValue(); |
| | | int destinationPosY = command.getDestinationPosY().intValue(); |
| | | int destinationPosZ = command.getDestinationPosZ().intValue(); |
| | | int taskMode = command.getTaskMode().intValue(); |
| | | int taskNo = command.getTaskNo().intValue(); |
| | | |
| | | if(command.getStation() == 1) { |
| | | this.crnStatus.setTaskNo(taskNo); |
| | | this.crnStatus.setStatus(CrnStatusType.FETCH_MOVING.id); |
| | | this.crnStatus.setTaskReceive(1); |
| | | |
| | | moveY(this.crnStatus.getBay(), destinationPosY, command.getStation().intValue()); |
| | | moveZ(this.crnStatus.getLevel(), destinationPosZ, command.getStation().intValue()); |
| | | this.crnStatus.setStatus(CrnStatusType.FETCHING.id); |
| | | sleep(2000); |
| | | if (Thread.currentThread().isInterrupted()) { |
| | | return; |
| | | } |
| | | this.crnStatus.setLoaded(1); |
| | | this.crnStatus.setStatus(CrnStatusType.WAITING.id); |
| | | }else { |
| | | this.crnStatus.setTaskNoTwo(taskNo); |
| | | this.crnStatus.setStatusTwo(CrnStatusType.FETCH_MOVING.id); |
| | | this.crnStatus.setTaskReceiveTwo(1); |
| | | |
| | | moveY(this.crnStatus.getBayTwo(), destinationPosY, command.getStation().intValue()); |
| | | moveZ(this.crnStatus.getLevelTwo(), destinationPosZ, command.getStation().intValue()); |
| | | this.crnStatus.setStatusTwo(CrnStatusType.FETCHING.id); |
| | | sleep(2000); |
| | | if (Thread.currentThread().isInterrupted()) { |
| | | return; |
| | | } |
| | | this.crnStatus.setLoadedTwo(1); |
| | | this.crnStatus.setStatusTwo(CrnStatusType.WAITING.id); |
| | | } |
| | | } |
| | | |
| | | private void commandPut(DualCrnCommand command) { |
| | | int destinationPosX = command.getDestinationPosX().intValue(); |
| | | int destinationPosY = command.getDestinationPosY().intValue(); |
| | | int destinationPosZ = command.getDestinationPosZ().intValue(); |
| | | int taskMode = command.getTaskMode().intValue(); |
| | | int taskNo = command.getTaskNo().intValue(); |
| | | |
| | | if(command.getStation() == 1) { |
| | | this.crnStatus.setTaskNo(taskNo); |
| | | this.crnStatus.setStatus(CrnStatusType.PUT_MOVING.id); |
| | | this.crnStatus.setTaskReceive(1); |
| | | |
| | | moveY(this.crnStatus.getBay(), destinationPosY, command.getStation().intValue()); |
| | | moveZ(this.crnStatus.getLevel(), destinationPosZ, command.getStation().intValue()); |
| | | this.crnStatus.setStatus(CrnStatusType.PUTTING.id); |
| | | sleep(2000); |
| | | if (Thread.currentThread().isInterrupted()) { |
| | | return; |
| | | } |
| | | this.crnStatus.setLoaded(0); |
| | | this.crnStatus.setStatus(CrnStatusType.WAITING.id); |
| | | }else { |
| | | this.crnStatus.setTaskNoTwo(taskNo); |
| | | this.crnStatus.setStatusTwo(CrnStatusType.PUT_MOVING.id); |
| | | this.crnStatus.setTaskReceiveTwo(1); |
| | | |
| | | moveY(this.crnStatus.getBayTwo(), destinationPosY, command.getStation().intValue()); |
| | | moveZ(this.crnStatus.getLevelTwo(), destinationPosZ, command.getStation().intValue()); |
| | | this.crnStatus.setStatusTwo(CrnStatusType.PUTTING.id); |
| | | sleep(2000); |
| | | if (Thread.currentThread().isInterrupted()) { |
| | | return; |
| | | } |
| | | this.crnStatus.setLoadedTwo(0); |
| | | this.crnStatus.setStatusTwo(CrnStatusType.WAITING.id); |
| | | } |
| | | } |
| | | |
| | | private void moveZ(int sourcePosZ, int destinationPosZ, int station) { |
| | | if(destinationPosZ - sourcePosZ > 0) { |
| | | int moveLength = destinationPosZ - sourcePosZ; |
| | |
| | | return new CommandResponse(true, "命令已受理(异步执行)"); |
| | | } |
| | | |
| | | @Override |
| | | public CommandResponse sendOriginCommand(String address, short[] data) { |
| | | return new CommandResponse(true, "原始命令已受理(异步执行)"); |
| | | } |
| | | |
| | | @Override |
| | | public byte[] readOriginCommand(String address, int length) { |
| | | return new byte[0]; |
| | | } |
| | | |
| | | private void handleCommand(Integer deviceNo, StationCommand command) { |
| | | News.info("[WCS Debug] 站点仿真模拟已启动,命令数据={}", JSON.toJSONString(command)); |
| | | Integer taskNo = command.getTaskNo(); |
| | |
| | | @Override |
| | | public CommandResponse sendCommand(DualCrnCommand command) { |
| | | CommandResponse response = new CommandResponse(false); |
| | | try { |
| | | if (null == command) { |
| | | News.error("双工位堆垛机写入命令为空"); |
| | | response.setMessage("双工位堆垛机写入命令为空"); |
| | | return response; |
| | | } |
| | | // try { |
| | | // if (null == command) { |
| | | // News.error("双工位堆垛机写入命令为空"); |
| | | // response.setMessage("双工位堆垛机写入命令为空"); |
| | | // return response; |
| | | // } |
| | | |
| | | String address = "DB100.0"; |
| | | if (command.getStation() == 1) { |
| | | //工位1 |
| | | address = "DB100.0"; |
| | | }else { |
| | | //工位2 |
| | | address = "DB100.20"; |
| | | } |
| | | // String address = "DB100.0"; |
| | | // if (command.getStation() == 1) { |
| | | // //工位1 |
| | | // address = "DB100.0"; |
| | | // }else { |
| | | // //工位2 |
| | | // address = "DB100.20"; |
| | | // } |
| | | |
| | | int writeAck = 0; |
| | | boolean ackResult = false; |
| | | do { |
| | | OperateResult resultAck = siemensNet.Write(address, (short) 0); |
| | | if (resultAck.IsSuccess) { |
| | | Thread.sleep(200); |
| | | OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 2); |
| | | short ack = siemensNet.getByteTransform().TransInt16(resultRead.Content, 0); |
| | | if (ack != 0) { |
| | | writeAck++; |
| | | } else { |
| | | News.info("双工位堆垛机命令下发[id:{}] >>>>> {}", command.getCrnNo(), "ack复位完成"); |
| | | ackResult = true; |
| | | break; |
| | | } |
| | | } |
| | | } while (writeAck < 5); |
| | | // int writeAck = 0; |
| | | // boolean ackResult = false; |
| | | // do { |
| | | // OperateResult resultAck = siemensNet.Write(address, (short) 0); |
| | | // if (resultAck.IsSuccess) { |
| | | // Thread.sleep(200); |
| | | // OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 2); |
| | | // short ack = siemensNet.getByteTransform().TransInt16(resultRead.Content, 0); |
| | | // if (ack != 0) { |
| | | // writeAck++; |
| | | // } else { |
| | | // News.info("双工位堆垛机命令下发[id:{}] >>>>> {}", command.getCrnNo(), "ack复位完成"); |
| | | // ackResult = true; |
| | | // break; |
| | | // } |
| | | // } |
| | | // } while (writeAck < 5); |
| | | |
| | | if (!ackResult) { |
| | | response.setMessage("双工位堆垛机命令下发[id:{}] >>>>> {}" + command.getCrnNo() + "ack复位失败"); |
| | | return response; |
| | | } |
| | | // if (!ackResult) { |
| | | // response.setMessage("双工位堆垛机命令下发[id:{}] >>>>> {}" + command.getCrnNo() + "ack复位失败"); |
| | | // return response; |
| | | // } |
| | | |
| | | short[] array = new short[10]; |
| | | array[0] = command.getAckFinish(); |
| | | array[1] = command.getTaskNo(); |
| | | array[2] = command.getTaskMode(); |
| | | array[3] = command.getSourcePosX(); |
| | | array[4] = command.getSourcePosY(); |
| | | array[5] = command.getSourcePosZ(); |
| | | array[6] = command.getDestinationPosX(); |
| | | array[7] = command.getDestinationPosY(); |
| | | array[8] = command.getDestinationPosZ(); |
| | | array[9] = command.getCommand(); |
| | | // short[] array = new short[10]; |
| | | // array[1] = command.getTaskNo(); |
| | | // array[2] = command.getTaskMode(); |
| | | // array[3] = command.getSourcePosX(); |
| | | // array[4] = command.getSourcePosY(); |
| | | // array[5] = command.getSourcePosZ(); |
| | | // array[6] = command.getDestinationPosX(); |
| | | // array[7] = command.getDestinationPosY(); |
| | | // array[8] = command.getDestinationPosZ(); |
| | | // array[9] = command.getCommand(); |
| | | |
| | | OperateResult result = null; |
| | | int idx = 0; |
| | | do { |
| | | OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 20); |
| | | if (resultRead.IsSuccess) { |
| | | if (command.getAckFinish() == 0) { |
| | | short taskNo = siemensNet.getByteTransform().TransInt16(resultRead.Content, 2); |
| | | short taskMode = siemensNet.getByteTransform().TransInt16(resultRead.Content, 4); |
| | | short sourcePosX = siemensNet.getByteTransform().TransInt16(resultRead.Content, 6); |
| | | short sourcePosY = siemensNet.getByteTransform().TransInt16(resultRead.Content, 8); |
| | | short sourcePosZ = siemensNet.getByteTransform().TransInt16(resultRead.Content, 10); |
| | | short destinationPosX = siemensNet.getByteTransform().TransInt16(resultRead.Content, 12); |
| | | short destinationPosY = siemensNet.getByteTransform().TransInt16(resultRead.Content, 14); |
| | | short destinationPosZ = siemensNet.getByteTransform().TransInt16(resultRead.Content, 16); |
| | | if (taskNo == 0 || taskMode == 0 || sourcePosX == 0 || sourcePosY == 0 || sourcePosZ == 0 || destinationPosX == 0 || destinationPosY == 0 || destinationPosZ == 0) { |
| | | result = siemensNet.Write(address, array); |
| | | } else { |
| | | break; |
| | | } |
| | | } else { |
| | | short ackFinish = siemensNet.getByteTransform().TransInt16(resultRead.Content, 0); |
| | | if (ackFinish != command.getAckFinish()) { |
| | | result = siemensNet.Write(address, array); |
| | | } else { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | idx++; |
| | | Thread.sleep(500); |
| | | } while (idx < 5); |
| | | // OperateResult result = null; |
| | | // int idx = 0; |
| | | // do { |
| | | // OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 20); |
| | | // if (resultRead.IsSuccess) { |
| | | // if (command.getAckFinish() == 0) { |
| | | // short taskNo = siemensNet.getByteTransform().TransInt16(resultRead.Content, 2); |
| | | // short taskMode = siemensNet.getByteTransform().TransInt16(resultRead.Content, 4); |
| | | // short sourcePosX = siemensNet.getByteTransform().TransInt16(resultRead.Content, 6); |
| | | // short sourcePosY = siemensNet.getByteTransform().TransInt16(resultRead.Content, 8); |
| | | // short sourcePosZ = siemensNet.getByteTransform().TransInt16(resultRead.Content, 10); |
| | | // short destinationPosX = siemensNet.getByteTransform().TransInt16(resultRead.Content, 12); |
| | | // short destinationPosY = siemensNet.getByteTransform().TransInt16(resultRead.Content, 14); |
| | | // short destinationPosZ = siemensNet.getByteTransform().TransInt16(resultRead.Content, 16); |
| | | // if (taskNo == 0 || taskMode == 0 || sourcePosX == 0 || sourcePosY == 0 || sourcePosZ == 0 || destinationPosX == 0 || destinationPosY == 0 || destinationPosZ == 0) { |
| | | // result = siemensNet.Write(address, array); |
| | | // } else { |
| | | // break; |
| | | // } |
| | | // } else { |
| | | // short ackFinish = siemensNet.getByteTransform().TransInt16(resultRead.Content, 0); |
| | | // if (ackFinish != command.getAckFinish()) { |
| | | // result = siemensNet.Write(address, array); |
| | | // } else { |
| | | // break; |
| | | // } |
| | | // } |
| | | // } |
| | | // idx++; |
| | | // Thread.sleep(500); |
| | | // } while (idx < 5); |
| | | |
| | | if (command.getAckFinish() == 0) { |
| | | short commandFinish = 1; |
| | | int i = 0; |
| | | do { |
| | | OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 4); |
| | | OperateResultExOne<byte[]> resultReadConfirm = siemensNet.Read(address + 18, (short) 2); |
| | | if (resultRead.IsSuccess && resultReadConfirm.IsSuccess) { |
| | | short taskNo = siemensNet.getByteTransform().TransInt16(resultRead.Content, 2); |
| | | short confirm = siemensNet.getByteTransform().TransInt16(resultReadConfirm.Content, 0); |
| | | if (taskNo != 0 && confirm == 0) { |
| | | result = siemensNet.Write(address + 18, commandFinish); |
| | | } |
| | | } |
| | | i++; |
| | | Thread.sleep(500); |
| | | } while (i < 5); |
| | | } |
| | | // if (command.getAckFinish() == 0) { |
| | | // short commandFinish = 1; |
| | | // int i = 0; |
| | | // do { |
| | | // OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 4); |
| | | // OperateResultExOne<byte[]> resultReadConfirm = siemensNet.Read(address + 18, (short) 2); |
| | | // if (resultRead.IsSuccess && resultReadConfirm.IsSuccess) { |
| | | // short taskNo = siemensNet.getByteTransform().TransInt16(resultRead.Content, 2); |
| | | // short confirm = siemensNet.getByteTransform().TransInt16(resultReadConfirm.Content, 0); |
| | | // if (taskNo != 0 && confirm == 0) { |
| | | // result = siemensNet.Write(address + 18, commandFinish); |
| | | // } |
| | | // } |
| | | // i++; |
| | | // Thread.sleep(500); |
| | | // } while (i < 5); |
| | | // } |
| | | |
| | | if (result != null && result.IsSuccess) { |
| | | News.info("SiemensDualCrn 双工位堆垛机命令下发[id:{}] >>>>> {}", command.getCrnNo(), JSON.toJSON(command)); |
| | | OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), command.getCrnNo(), JSON.toJSON(command))); |
| | | response.setResult(true); |
| | | response.setMessage("命令下发成功"); |
| | | } else { |
| | | News.error("SiemensDualCrn 双工位堆垛机写入堆垛机plc数据失败 ===>> [id:{}]", command.getCrnNo()); |
| | | OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}]", DateUtils.convert(new Date()), command.getCrnNo())); |
| | | response.setResult(false); |
| | | response.setMessage("命令下发失败"); |
| | | } |
| | | // if (result != null && result.IsSuccess) { |
| | | // News.info("SiemensDualCrn 双工位堆垛机命令下发[id:{}] >>>>> {}", command.getCrnNo(), JSON.toJSON(command)); |
| | | // OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), command.getCrnNo(), JSON.toJSON(command))); |
| | | // response.setResult(true); |
| | | // response.setMessage("命令下发成功"); |
| | | // } else { |
| | | // News.error("SiemensDualCrn 双工位堆垛机写入堆垛机plc数据失败 ===>> [id:{}]", command.getCrnNo()); |
| | | // OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}]", DateUtils.convert(new Date()), command.getCrnNo())); |
| | | // response.setResult(false); |
| | | // response.setMessage("命令下发失败"); |
| | | // } |
| | | |
| | | return response; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | }finally { |
| | | String sourceLocNo = Utils.getLocNo(command.getSourcePosX(), command.getSourcePosY(), command.getSourcePosZ()); |
| | | String targetLocNo = Utils.getLocNo(command.getDestinationPosX(), command.getDestinationPosY(), command.getDestinationPosZ()); |
| | | // return response; |
| | | // } catch (Exception e) { |
| | | // e.printStackTrace(); |
| | | // }finally { |
| | | // String sourceLocNo = Utils.getLocNo(command.getSourcePosX(), command.getSourcePosY(), command.getSourcePosZ()); |
| | | // String targetLocNo = Utils.getLocNo(command.getDestinationPosX(), command.getDestinationPosY(), command.getDestinationPosZ()); |
| | | |
| | | // 日志记录 |
| | | BasCrnpOptService bean = SpringUtils.getBean(BasCrnpOptService.class); |
| | | BasCrnpOpt basCrnpOpt = new BasCrnpOpt( |
| | | command.getTaskNo().intValue(), // 任务号 |
| | | command.getCrnNo(), // 堆垛机[非空] |
| | | new Date(), // 下发时间 |
| | | String.valueOf(command.getTaskMode()), // 模式 |
| | | sourceLocNo, //源库位 |
| | | targetLocNo, //目标库位 |
| | | null, // 修改时间 |
| | | null, // 修改人员 |
| | | null, // 备注 |
| | | JSON.toJSONString(command), // 指令 |
| | | JSON.toJSONString(getStatus()), // 系统状态 |
| | | 1, // 下发状态{0:未下发,1:已下发} |
| | | JSON.toJSONString(response) // 响应 |
| | | ); |
| | | bean.insert(basCrnpOpt); |
| | | } |
| | | // // 日志记录 |
| | | // BasCrnpOptService bean = SpringUtils.getBean(BasCrnpOptService.class); |
| | | // BasCrnpOpt basCrnpOpt = new BasCrnpOpt( |
| | | // command.getTaskNo().intValue(), // 任务号 |
| | | // command.getCrnNo(), // 堆垛机[非空] |
| | | // new Date(), // 下发时间 |
| | | // String.valueOf(command.getTaskMode()), // 模式 |
| | | // sourceLocNo, //源库位 |
| | | // targetLocNo, //目标库位 |
| | | // null, // 修改时间 |
| | | // null, // 修改人员 |
| | | // null, // 备注 |
| | | // JSON.toJSONString(command), // 指令 |
| | | // JSON.toJSONString(getStatus()), // 系统状态 |
| | | // 1, // 下发状态{0:未下发,1:已下发} |
| | | // JSON.toJSONString(response) // 响应 |
| | | // ); |
| | | // bean.insert(basCrnpOpt); |
| | | // } |
| | | return response; |
| | | } |
| | | } |
| | |
| | | return commandResponse; |
| | | } |
| | | |
| | | @Override |
| | | public CommandResponse sendOriginCommand(String address, short[] data) { |
| | | CommandResponse commandResponse = new CommandResponse(false); |
| | | if (null == data || data.length == 0) { |
| | | commandResponse.setMessage("数据为空"); |
| | | return commandResponse; |
| | | } |
| | | |
| | | OperateResult write = siemensNet.Write(address, data); |
| | | if (write.IsSuccess) { |
| | | log.info("写入原始命令成功。地址={},数据={}", address, JSON.toJSON(data)); |
| | | commandResponse.setResult(true); |
| | | } else { |
| | | log.error("写入原始命令失败。地址={},数据={}", address, JSON.toJSON(data)); |
| | | commandResponse.setResult(false); |
| | | } |
| | | return commandResponse; |
| | | } |
| | | |
| | | @Override |
| | | public byte[] readOriginCommand(String address, int length) { |
| | | OperateResultExOne<byte[]> result = siemensNet.Read(address, (short) length); |
| | | if (result.IsSuccess) { |
| | | return result.Content; |
| | | } |
| | | return new byte[0]; |
| | | } |
| | | |
| | | private ZyStationStatusEntity findStatusEntity(Integer stationId) { |
| | | for (ZyStationStatusEntity statusEntity : statusList) { |
| | | if (statusEntity.getStationId().equals(stationId)) { |
| | |
| | | |
| | | DualCrnCommand getPickAndPutCommand(String sourceLocNo, String targetLocNo, Integer taskNo, Integer crnNo, Integer station);//取放货 |
| | | |
| | | DualCrnCommand getPickCommand(String targetLocNo, Integer taskNo, Integer crnNo, Integer station);//取货 |
| | | |
| | | DualCrnCommand getPutCommand(String targetLocNo, Integer taskNo, Integer crnNo, Integer station);//放货 |
| | | |
| | | DualCrnCommand getMoveCommand(String targetLocNo, Integer taskNo, Integer crnNo);//移动 |
| | | |
| | | DualCrnCommand getResetCommand(Integer crnNo, Integer station);//复位 |
| | |
| | | |
| | | CommandResponse sendCommand(StationCommand command); |
| | | |
| | | CommandResponse sendOriginCommand(String address, short[] data); |
| | | |
| | | byte[] readOriginCommand(String address, int length); |
| | | |
| | | } |
| | |
| | | import com.zy.common.utils.RedisUtil; |
| | | import com.zy.core.cache.MessageQueue; |
| | | import com.zy.core.cache.OutputQueue; |
| | | import com.zy.core.enums.CrnTaskModeType; |
| | | import com.zy.core.enums.DualCrnTaskModeType; |
| | | import com.zy.core.enums.RedisKeyType; |
| | | import com.zy.core.enums.SlaveType; |
| | | import com.zy.core.model.CommandResponse; |
| | |
| | | crnProtocol.setForkPos(-1); |
| | | crnProtocol.setLoaded(0); |
| | | crnProtocol.setWalkPos(0); |
| | | crnProtocol.setLiftPos(0); |
| | | |
| | | //工位2 |
| | | crnProtocol.setTaskNoTwo(0); |
| | |
| | | crnProtocol.setForkPosTwo(-1); |
| | | crnProtocol.setLoadedTwo(0); |
| | | crnProtocol.setWalkPosTwo(0); |
| | | crnProtocol.setLiftPosTwo(0); |
| | | |
| | | crnProtocol.setAlarm(0); |
| | | crnProtocol.setXSpeed(0); |
| | |
| | | OutputQueue.DUAL_CRN.offer(MessageFormat.format("【{0}】读取双工位堆垛机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), deviceConfig.getDeviceNo(), deviceConfig.getIp(), deviceConfig.getPort())); |
| | | return; |
| | | } |
| | | |
| | | crnProtocol.setMode(crnStatus.getMode()); |
| | | |
| | | //工位1 |
| | |
| | | crnProtocol.setForkPos(crnStatus.getForkPos()); |
| | | crnProtocol.setLoaded(crnStatus.getLoaded()); |
| | | crnProtocol.setWalkPos(crnStatus.getWalkPos()); |
| | | crnProtocol.setLiftPos(crnStatus.getLiftPos()); |
| | | crnProtocol.setTaskReceive(crnStatus.getTaskReceive()); |
| | | |
| | | //工位2 |
| | | crnProtocol.setTaskNoTwo(crnStatus.getTaskNoTwo()); |
| | |
| | | crnProtocol.setForkPosTwo(crnStatus.getForkPosTwo()); |
| | | crnProtocol.setLoadedTwo(crnStatus.getLoadedTwo()); |
| | | crnProtocol.setWalkPosTwo(crnStatus.getWalkPosTwo()); |
| | | crnProtocol.setLiftPosTwo(crnStatus.getLiftPosTwo()); |
| | | crnProtocol.setTaskReceiveTwo(crnStatus.getTaskReceiveTwo()); |
| | | |
| | | crnProtocol.setAlarm(crnStatus.getAlarm()); |
| | | crnProtocol.setTemp1(crnStatus.getTemp1()); |
| | |
| | | DualCrnCommand crnCommand = new DualCrnCommand(); |
| | | crnCommand.setCrnNo(crnNo); // 堆垛机编号 |
| | | crnCommand.setTaskNo(taskNo.shortValue()); // 工作号 |
| | | crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE.id.shortValue()); // 任务模式: 库位移转 |
| | | crnCommand.setTaskMode(DualCrnTaskModeType.TRANSFER.id.shortValue()); // 任务模式: 取放货 |
| | | crnCommand.setSourcePosX((short) Utils.getRow(sourceLocNo)); // 源库位排 |
| | | crnCommand.setSourcePosY((short) Utils.getBay(sourceLocNo)); // 源库位列 |
| | | crnCommand.setSourcePosZ((short) Utils.getLev(sourceLocNo)); // 源库位层 |
| | | crnCommand.setDestinationPosX((short) Utils.getRow(targetLocNo)); // 目标库位排 |
| | | crnCommand.setDestinationPosY((short) Utils.getBay(targetLocNo)); // 目标库位列 |
| | | crnCommand.setDestinationPosZ((short) Utils.getLev(targetLocNo)); // 目标库位层 |
| | | crnCommand.setStation(station.shortValue());//工位 |
| | | crnCommand.setCommand((short) 1); // 任务确认 |
| | | return crnCommand; |
| | | } |
| | | |
| | | @Override |
| | | public DualCrnCommand getPickCommand(String targetLocNo, Integer taskNo, Integer crnNo, Integer station) { |
| | | DualCrnCommand crnCommand = new DualCrnCommand(); |
| | | crnCommand.setCrnNo(crnNo); // 堆垛机编号 |
| | | crnCommand.setTaskNo(taskNo.shortValue()); // 工作号 |
| | | crnCommand.setTaskMode(DualCrnTaskModeType.PICK.id.shortValue()); // 任务模式: 取货 |
| | | crnCommand.setDestinationPosX((short) Utils.getRow(targetLocNo)); // 目标库位排 |
| | | crnCommand.setDestinationPosY((short) Utils.getBay(targetLocNo)); // 目标库位列 |
| | | crnCommand.setDestinationPosZ((short) Utils.getLev(targetLocNo)); // 目标库位层 |
| | | crnCommand.setStation(station.shortValue());//工位 |
| | | crnCommand.setCommand((short) 1); // 任务确认 |
| | | return crnCommand; |
| | | } |
| | | |
| | | @Override |
| | | public DualCrnCommand getPutCommand(String targetLocNo, Integer taskNo, Integer crnNo, Integer station) { |
| | | DualCrnCommand crnCommand = new DualCrnCommand(); |
| | | crnCommand.setCrnNo(crnNo); // 堆垛机编号 |
| | | crnCommand.setTaskNo(taskNo.shortValue()); // 工作号 |
| | | crnCommand.setTaskMode(DualCrnTaskModeType.PUT.id.shortValue()); // 任务模式: 放货 |
| | | crnCommand.setDestinationPosX((short) Utils.getRow(targetLocNo)); // 目标库位排 |
| | | crnCommand.setDestinationPosY((short) Utils.getBay(targetLocNo)); // 目标库位列 |
| | | crnCommand.setDestinationPosZ((short) Utils.getLev(targetLocNo)); // 目标库位层 |
| | |
| | | DualCrnCommand crnCommand = new DualCrnCommand(); |
| | | crnCommand.setCrnNo(crnNo); // 堆垛机编号 |
| | | crnCommand.setTaskNo(taskNo.shortValue()); // 工作号 |
| | | crnCommand.setAckFinish((short) 0); // 任务完成确认位 |
| | | crnCommand.setTaskMode(CrnTaskModeType.CRN_MOVE.id.shortValue()); // 任务模式: 堆垛机移动 |
| | | crnCommand.setTaskMode(DualCrnTaskModeType.MOVE.id.shortValue()); // 任务模式: 堆垛机移动 |
| | | crnCommand.setDestinationPosX((short) Utils.getRow(targetLocNo)); // 目标库位排 |
| | | crnCommand.setDestinationPosY((short) Utils.getBay(targetLocNo)); // 目标库位列 |
| | | crnCommand.setDestinationPosZ((short) Utils.getLev(targetLocNo)); // 目标库位层 |
| | |
| | | DualCrnCommand crnCommand = new DualCrnCommand(); |
| | | crnCommand.setCrnNo(crnNo); // 堆垛机编号 |
| | | crnCommand.setTaskNo((short) 0); // 工作号 |
| | | crnCommand.setAckFinish((short) 1); // 任务完成确认位 |
| | | crnCommand.setTaskMode(CrnTaskModeType.NONE.id.shortValue()); // 任务模式 |
| | | crnCommand.setTaskMode(DualCrnTaskModeType.CONFIRM.id.shortValue()); // 任务模式: 确认 |
| | | crnCommand.setSourcePosX((short)0); // 源库位排 |
| | | crnCommand.setSourcePosY((short)0); // 源库位列 |
| | | crnCommand.setSourcePosZ((short)0); // 源库位层 |
| | |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | @Override |
| | | public CommandResponse sendOriginCommand(String address, short[] data) { |
| | | return zyStationConnectDriver.sendOriginCommand(address, data); |
| | | } |
| | | |
| | | @Override |
| | | public byte[] readOriginCommand(String address, int length) { |
| | | return zyStationConnectDriver.readOriginCommand(address, length); |
| | | } |
| | | } |
| | |
| | | <el-descriptions-item label="托盘高度">{{ item.palletHeight }}</el-descriptions-item> |
| | | <el-descriptions-item label="条码">{{ item.barcode }}</el-descriptions-item> |
| | | <el-descriptions-item label="故障代码">{{ item.error }}</el-descriptions-item> |
| | | <el-descriptions-item label="扩展数据">{{ item.extend }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </el-collapse-item> |
| | | </el-collapse> |
| | |
| | | currentLev: 1, |
| | | mapFps: 0, |
| | | ws: null, |
| | | wsReconnectTimer: null, |
| | | wsReconnectAttempts: 0, |
| | | wsReconnectBaseDelay: 1000, |
| | | wsReconnectMaxDelay: 15000, |
| | | pixiApp: null, |
| | | pixiStageList: [], |
| | | pixiStaMap: new Map(), |
| | | pixiCrnMap: new Map(), |
| | | pixiDualCrnMap: new Map(), |
| | | pixiRgvMap: new Map(), |
| | | pixiShelfMap: new Map(), |
| | | pixiTrackMap: new Map(), |
| | |
| | | pixiCrnColorTextureMap: new Map(), |
| | | pixiRgvColorTextureMap: new Map(), |
| | | crnList: [], |
| | | dualCrnList: [], |
| | | rgvList: [], |
| | | objectsContainer: null, |
| | | objectsContainer2: null, |
| | |
| | | isSwitchingFloor: false |
| | | } |
| | | }, |
| | | mounted() { |
| | | mounted() { |
| | | this.currentLev = this.lev || 1; |
| | | this.createMap(); |
| | | this.ws = new WebSocket("ws://" + window.location.host + baseUrl + "/console/websocket"); |
| | | this.ws.onopen = this.webSocketOnOpen; |
| | | this.ws.onerror = this.webSocketOnError; |
| | | this.ws.onmessage = this.webSocketOnMessage; |
| | | this.ws.onclose = this.webSocketClose; |
| | | this.connectWs(); |
| | | |
| | | setTimeout(() => { |
| | | this.getMap(this.currentLev); |
| | |
| | | |
| | | this.timer = setInterval(() => { |
| | | this.getCrnInfo(); |
| | | this.getDualCrnInfo(); |
| | | this.getSiteInfo(); |
| | | this.getRgvInfo(); |
| | | }, 1000); |
| | |
| | | if (this.timer) { clearInterval(this.timer); } |
| | | if (this.pixiApp) { this.pixiApp.destroy(true, { children: true }); } |
| | | window.removeEventListener('resize', this.resizeToContainer); |
| | | if (this.wsReconnectTimer) { clearTimeout(this.wsReconnectTimer); this.wsReconnectTimer = null; } |
| | | if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) { try { this.ws.close(); } catch (e) {} } |
| | | }, |
| | | watch: { |
| | | lev(newLev) { |
| | |
| | | |
| | | //*******************FPS******************* |
| | | let g_Time = 0; |
| | | let fpsLastUpdateTs = 0; |
| | | let fpsDeltaSumMs = 0; |
| | | let fpsFrameCount = 0; |
| | | const fpsUpdateInterval = 200; |
| | | this.pixiApp.ticker.add((delta) => { |
| | | const timeNow = (new Date()).getTime(); |
| | | const timeDiff = timeNow - g_Time; |
| | | g_Time = timeNow; |
| | | const fps = 1000 / timeDiff; |
| | | this.mapFps = parseInt(fps); |
| | | fpsDeltaSumMs += timeDiff; |
| | | fpsFrameCount += 1; |
| | | if (timeNow - fpsLastUpdateTs >= fpsUpdateInterval) { |
| | | const avgFps = fpsDeltaSumMs > 0 ? (fpsFrameCount * 1000 / fpsDeltaSumMs) : 0; |
| | | this.mapFps = Math.round(avgFps); |
| | | fpsDeltaSumMs = 0; |
| | | fpsFrameCount = 0; |
| | | fpsLastUpdateTs = timeNow; |
| | | } |
| | | }); |
| | | //*******************FPS******************* |
| | | }, |
| | |
| | | if (this.tracksContainer) { this.tracksContainer.removeChildren(); } |
| | | if (this.shelvesContainer) { this.shelvesContainer.removeChildren(); } |
| | | this.crnList = []; |
| | | this.dualCrnList = []; |
| | | this.rgvList = []; |
| | | this.pixiCrnMap = new Map(); |
| | | this.pixiDualCrnMap = new Map(); |
| | | this.pixiRgvMap = new Map(); |
| | | this.pixiStaMap = new Map(); |
| | | this.pixiStageList = []; |
| | | this.getMap(); |
| | | }, |
| | | createMapData(map) { |
| | | this.pixiStageList = [map.length]; |
| | | this.pixiStaMap = new Map(); |
| | | if (window.gsap) { |
| | | this.pixiStaMap && this.pixiStaMap.forEach((s) => { try { window.gsap.killTweensOf(s); } catch (e) {} }); |
| | | this.pixiCrnMap && this.pixiCrnMap.forEach((s) => { try { window.gsap.killTweensOf(s); } catch (e) {} }); |
| | | this.pixiDualCrnMap && this.pixiDualCrnMap.forEach((s) => { try { window.gsap.killTweensOf(s); } catch (e) {} }); |
| | | this.pixiRgvMap && this.pixiRgvMap.forEach((s) => { try { window.gsap.killTweensOf(s); } catch (e) {} }); |
| | | } |
| | | this.objectsContainer.removeChildren(); |
| | | this.objectsContainer2.removeChildren(); |
| | | if (this.tracksContainer) { this.tracksContainer.removeChildren(); } |
| | | if (this.shelvesContainer) { this.shelvesContainer.removeChildren(); } |
| | | this.crnList = []; |
| | | this.dualCrnList = []; |
| | | this.rgvList = []; |
| | | this.pixiCrnMap = new Map(); |
| | | this.pixiDualCrnMap = new Map(); |
| | | this.pixiRgvMap = new Map(); |
| | | this.pixiStaMap = new Map(); |
| | | this.pixiStageList = []; |
| | | this.pixiStageList = [map.length]; |
| | | const bayHeightList = this.initHeight(map); |
| | | const bayWidthList = this.initWidth(map); |
| | | map.forEach((item, index) => { |
| | |
| | | this.objectsContainer2.addChild(sprite); |
| | | }); |
| | | |
| | | this.dualCrnList.forEach((item) => { |
| | | if (this.graphicsCrn == null) { this.graphicsCrn = this.createCrnTexture(item.width * 0.9, item.height * 0.9); } |
| | | let sprite = new PIXI.Sprite(this.graphicsCrn); |
| | | const deviceNo = this.getDeviceNo(item.value); |
| | | const taskNo = this.getTaskNo(item.value); |
| | | const style = new PIXI.TextStyle({ fontFamily: 'Arial', fontSize: 12, fill: '#000000', stroke: '#ffffff', strokeThickness: 1 }); |
| | | const txt = taskNo > 0 ? (deviceNo + "(" + taskNo + ")") : String(deviceNo); |
| | | const text = new PIXI.Text(txt, style); |
| | | text.anchor.set(0.5); |
| | | text.position.set(sprite.width / 2, sprite.height / 2); |
| | | sprite.addChild(text); |
| | | sprite.textObj = text; |
| | | sprite.position.set(item.posX, item.posY); |
| | | sprite.interactive = true; |
| | | sprite.buttonMode = true; |
| | | sprite.on('pointerdown', () => { |
| | | if (window.gsap) { window.gsap.killTweensOf(sprite); } |
| | | sprite.alpha = 1; |
| | | const id = parseInt(deviceNo, 10); |
| | | this.$emit('dual-crn-click', id); |
| | | }); |
| | | let rowIndexForCrn = 0; |
| | | for (let r = 0; r < map.length; r++) { |
| | | if (map[r].length > 0) { |
| | | const rowY = map[r][0].posY; |
| | | if (Math.abs(rowY - item.posY) < 0.5) { rowIndexForCrn = r; break; } |
| | | } |
| | | } |
| | | sprite.rowIndex = rowIndexForCrn; |
| | | this.pixiDualCrnMap.set(parseInt(deviceNo), sprite); |
| | | this.objectsContainer2.addChild(sprite); |
| | | }); |
| | | |
| | | this.rgvList.forEach((item) => { |
| | | if (this.graphicsRgv == null) { this.graphicsRgv = this.createRgvTexture(item.width * 0.9, item.height * 0.9); } |
| | | let sprite = new PIXI.Sprite(this.graphicsRgv); |
| | |
| | | if (this.isSwitchingFloor) { return; } |
| | | this.sendWs(JSON.stringify({ url: "/console/latest/data/crn", data: {} })); |
| | | }, |
| | | getDualCrnInfo() { |
| | | if (this.isSwitchingFloor) { return; } |
| | | this.sendWs(JSON.stringify({ url: "/console/latest/data/dualcrn", data: {} })); |
| | | }, |
| | | getSiteInfo() { |
| | | if (this.isSwitchingFloor) { return; } |
| | | this.sendWs(JSON.stringify({ url: "/console/latest/data/station", data: {} })); |
| | |
| | | for (let c = this.map[rowIndex].length - 1; c >= 0; c--) { |
| | | const cell = this.map[rowIndex][c]; |
| | | if (cell && cell.type === 'crn') { targetCell = cell; break; } |
| | | } |
| | | } |
| | | if (!targetCell) { continue; } |
| | | const targetX = targetCell.posX + (targetCell.width - sprite.width) / 2; |
| | | const dx = Math.abs(targetX - sprite.x); |
| | | if (dx < 1) { |
| | | } else if (dx < 5) { |
| | | sprite.x = targetX; |
| | | } else if (window.gsap) { |
| | | window.gsap.killTweensOf(sprite); |
| | | window.gsap.to(sprite, { x: targetX, duration: 0.3, ease: "power1.inOut" }); |
| | | } else { |
| | | sprite.x = targetX; |
| | | } |
| | | } |
| | | this.scheduleAdjustLabels(); |
| | | }, |
| | | setDualCrnInfo(res) { |
| | | let crns = Array.isArray(res) ? res : (res && res.code === 200 ? res.data : null); |
| | | if (!crns) { return; } |
| | | for (var i = 0; i < crns.length; i++) { |
| | | const id = parseInt(crns[i].crnId); |
| | | const sprite = this.pixiDualCrnMap.get(id); |
| | | if (!sprite) { continue; } |
| | | const taskNo = crns[i].taskNo; |
| | | if (taskNo != null && taskNo > 0) { sprite.textObj.text = id + "(" + taskNo + ")"; } else { sprite.textObj.text = String(id); } |
| | | const status = crns[i].crnStatus; |
| | | const statusColor = this.getCrnStatusColor(status); |
| | | this.updateCrnTextureColor(sprite, statusColor); |
| | | let bay = parseInt(crns[i].bay, 10); |
| | | if (isNaN(bay) || bay < 1 || bay === -2) { bay = 1; } |
| | | let rowIndex = (sprite.rowIndex != null) ? sprite.rowIndex : -1; |
| | | if (rowIndex === -1) { |
| | | for (let r = 0; r < this.map.length; r++) { |
| | | if (this.map[r].length > 0) { |
| | | const rowY = this.map[r][0].posY; |
| | | if (Math.abs(rowY - sprite.y) < 0.5) { rowIndex = r; break; } |
| | | } |
| | | } |
| | | if (rowIndex === -1) { rowIndex = 0; } |
| | | } |
| | | let targetCell = null; |
| | | let crnCount = 0; |
| | | for (let c = 0; c < this.map[rowIndex].length; c++) { |
| | | const cell = this.map[rowIndex][c]; |
| | | if (cell && (cell.type === 'dualCrn' || cell.type === 'dualcrn')) { |
| | | crnCount++; |
| | | if (crnCount === bay) { targetCell = cell; break; } |
| | | } |
| | | } |
| | | if (!targetCell) { |
| | | for (let c = this.map[rowIndex].length - 1; c >= 0; c--) { |
| | | const cell = this.map[rowIndex][c]; |
| | | if (cell && (cell.type === 'dualCrn' || cell.type === 'dualcrn')) { targetCell = cell; break; } |
| | | } |
| | | } |
| | | if (!targetCell) { continue; } |
| | |
| | | this.createMapData(JSON.parse(res.data)); |
| | | }, |
| | | webSocketOnOpen(e) { |
| | | if (this.wsReconnectTimer) { clearTimeout(this.wsReconnectTimer); this.wsReconnectTimer = null; } |
| | | this.wsReconnectAttempts = 0; |
| | | this.getMap(this.currentLev); |
| | | }, |
| | | webSocketOnError(e) { |
| | | this.scheduleReconnect(); |
| | | }, |
| | | webSocketOnMessage(e) { |
| | | const result = JSON.parse(e.data); |
| | |
| | | this.setSiteInfo(JSON.parse(result.data)); |
| | | } else if (result.url === "/console/latest/data/crn") { |
| | | this.setCrnInfo(JSON.parse(result.data)); |
| | | } else if (result.url === "/console/latest/data/dualcrn") { |
| | | this.setDualCrnInfo(JSON.parse(result.data)); |
| | | } else if (result.url === "/console/latest/data/rgv") { |
| | | this.setRgvInfo(JSON.parse(result.data)); |
| | | } else if (typeof result.url === "string" && result.url.indexOf("/basMap/lev/") === 0) { |
| | |
| | | } |
| | | }, |
| | | webSocketClose(e) { |
| | | this.scheduleReconnect(); |
| | | }, |
| | | sendWs(message) { |
| | | if (this.ws && this.ws.readyState === WebSocket.OPEN) { |
| | | this.ws.send(message); |
| | | } |
| | | }, |
| | | connectWs() { |
| | | if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) { return; } |
| | | this.ws = new WebSocket("ws://" + window.location.host + baseUrl + "/console/websocket"); |
| | | this.ws.onopen = this.webSocketOnOpen; |
| | | this.ws.onerror = this.webSocketOnError; |
| | | this.ws.onmessage = this.webSocketOnMessage; |
| | | this.ws.onclose = this.webSocketClose; |
| | | }, |
| | | scheduleReconnect() { |
| | | if (this.wsReconnectTimer) { return; } |
| | | const attempt = this.wsReconnectAttempts + 1; |
| | | const jitter = Math.floor(Math.random() * 300); |
| | | const delay = Math.min(this.wsReconnectMaxDelay, this.wsReconnectBaseDelay * Math.pow(2, this.wsReconnectAttempts)) + jitter; |
| | | this.wsReconnectTimer = setTimeout(() => { |
| | | this.wsReconnectTimer = null; |
| | | this.wsReconnectAttempts = attempt; |
| | | this.connectWs(); |
| | | }, delay); |
| | | }, |
| | | createShelfSprite(width, height) { |
| | | let idx = width + "-" + height; |
| | |
| | | sprite = this.createTrackSprite(item.width, item.height); |
| | | sprite._kind = 'crn-track'; |
| | | if (this.getDeviceNo(value) > 0) { this.crnList.push(item); } |
| | | } else if (item.type == 'dualCrn') { |
| | | sprite = this.createTrackSprite(item.width, item.height); |
| | | sprite._kind = 'crn-track'; |
| | | if (this.getDeviceNo(value) > 0) { this.dualCrnList.push(item); } |
| | | } else if (item.type == 'rgv') { |
| | | sprite = this.createTrackSprite(item.width, item.height); |
| | | sprite._kind = 'rgv-track'; |
| | |
| | | const on = sx >= -margin && sy >= -margin && sx <= vw + margin && sy <= vh + margin; |
| | | textObj.visible = (s >= 0.25) && on; |
| | | }); |
| | | this.pixiDualCrnMap && this.pixiDualCrnMap.forEach((sprite) => { |
| | | const textObj = sprite && sprite.textObj; |
| | | if (!textObj) { return; } |
| | | const base = (textObj.style && textObj.style.fontSize) ? textObj.style.fontSize : 12; |
| | | let scale = minPx / (base * s); |
| | | if (!isFinite(scale)) { scale = 1; } |
| | | scale = Math.max(0.8, Math.min(scale, 3)); |
| | | textObj.scale.set(scale); |
| | | textObj.position.set(sprite.width / 2, sprite.height / 2); |
| | | const sx = pos.x + sprite.x * s; |
| | | const sy = pos.y + sprite.y * s; |
| | | const on = sx >= -margin && sy >= -margin && sx <= vw + margin && sy <= vh + margin; |
| | | textObj.visible = (s >= 0.25) && on; |
| | | }); |
| | | this.pixiRgvMap && this.pixiRgvMap.forEach((sprite) => { |
| | | const textObj = sprite && sprite.textObj; |
| | | if (!textObj) { return; } |
| | |
| | | <el-descriptions-item label="升降距离(Km)">{{ item.ydistance }}</el-descriptions-item> |
| | | <el-descriptions-item label="走行时长(H)">{{ item.xDuration }}</el-descriptions-item> |
| | | <el-descriptions-item label="升降时长(H)">{{ item.yduration }}</el-descriptions-item> |
| | | <el-descriptions-item label="称重数据">{{ item.weight }}</el-descriptions-item> |
| | | <el-descriptions-item label="条码数据">{{ item.barcode }}</el-descriptions-item> |
| | | <el-descriptions-item label="故障代码">{{ item.warnCode }}</el-descriptions-item> |
| | | <el-descriptions-item label="故障描述">{{ item.alarm }}</el-descriptions-item> |
| | | <el-descriptions-item label="扩展数据">{{ item.extend }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </el-collapse-item> |
| | | </el-collapse> |
| New file |
| | |
| | | Vue.component("watch-dual-crn-card", { |
| | | template: ` |
| | | <div> |
| | | <div style="display: flex;margin-bottom: 10px;"> |
| | | <div style="width: 100%;">双工位堆垛机监控</div> |
| | | <div style="width: 100%;text-align: right;display: flex;"> |
| | | <el-input size="mini" v-model="searchCrnNo" placeholder="请输入堆垛机号"></el-input> |
| | | <el-button @click="getDualCrnStateInfo" size="mini">查询</el-button> |
| | | </div> |
| | | </div> |
| | | <div style="margin-bottom: 10px;"> |
| | | <div style="margin-bottom: 5px;"> |
| | | <el-button v-if="showControl" @click="openControl" size="mini">关闭控制中心</el-button> |
| | | <el-button v-else @click="openControl" size="mini">打开控制中心</el-button> |
| | | </div> |
| | | <div v-if="showControl" style="display: flex;justify-content: space-between;flex-wrap: wrap;"> |
| | | <div style="margin-bottom: 10px;width: 33%;"><el-input size="mini" v-model="controlParam.crnNo" placeholder="堆垛机号"></el-input></div> |
| | | <div style="margin-bottom: 10px;width: 33%;"><el-input size="mini" v-model="controlParam.sourceLocNo" placeholder="源点"></el-input></div> |
| | | <div style="margin-bottom: 10px;width: 33%;"><el-input size="mini" v-model="controlParam.targetLocNo" placeholder="目标点"></el-input></div> |
| | | <div style="margin-bottom: 10px;width: 33%;"> |
| | | <el-select size="mini" v-model="controlParam.station" placeholder="工位"> |
| | | <el-option :label="'工位1'" :value="1"></el-option> |
| | | <el-option :label="'工位2'" :value="2"></el-option> |
| | | </el-select> |
| | | </div> |
| | | <div style="margin-bottom: 10px;"><el-button @click="controlCommandTransport()" size="mini">取放货</el-button></div> |
| | | <div style="margin-bottom: 10px;"><el-button @click="controlCommandPickup()" size="mini">取货</el-button></div> |
| | | <div style="margin-bottom: 10px;"><el-button @click="controlCommandPutdown()" size="mini">放货</el-button></div> |
| | | <div style="margin-bottom: 10px;"><el-button @click="controlCommandMove()" size="mini">移动</el-button></div> |
| | | <div style="margin-bottom: 10px;"><el-button @click="controlCommandTaskComplete()" size="mini">任务完成</el-button></div> |
| | | </div> |
| | | </div> |
| | | <div style="max-height: 55vh; overflow:auto;"> |
| | | <el-collapse v-model="activeNames" accordion> |
| | | <el-collapse-item v-for="(item) in displayCrnList" :name="item.crnNo"> |
| | | <template slot="title"> |
| | | <div style="width: 100%;display: flex;"> |
| | | <div style="width: 50%;">{{ item.crnNo }}号双工位堆垛机</div> |
| | | <div style="width: 50%;text-align: right;"> |
| | | <el-tag v-if="item.deviceStatus == 'AUTO'" type="success" size="small">自动</el-tag> |
| | | <el-tag v-else-if="item.deviceStatus == 'WORKING'" size="small">作业中</el-tag> |
| | | <el-tag v-else-if="item.deviceStatus == 'ERROR'" type="danger" size="small">故障</el-tag> |
| | | <el-tag v-else type="warning" size="small">离线</el-tag> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <el-descriptions border direction="vertical"> |
| | | <el-descriptions-item label="模式">{{ item.mode }}</el-descriptions-item> |
| | | <el-descriptions-item label="异常码">{{ item.warnCode }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位1任务号">{{ item.taskNo }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位2任务号">{{ item.taskNoTwo }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位1状态">{{ item.status }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位2状态">{{ item.statusTwo }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位1是否有物">{{ item.loading }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位2是否有物">{{ item.loadingTwo }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位1列">{{ item.bay }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位2列">{{ item.bayTwo }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位1层">{{ item.lev }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位2层">{{ item.levTwo }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位1货叉定位">{{ item.forkOffset }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位2货叉定位">{{ item.forkOffsetTwo }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位1载货台定位">{{ item.liftPos }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位2载货台定位">{{ item.liftPosTwo }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位1走行在定位">{{ item.walkPos }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位2走行在定位">{{ item.walkPosTwo }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位1任务接收">{{ item.taskReceive }}</el-descriptions-item> |
| | | <el-descriptions-item label="工位2任务接收">{{ item.taskReceiveTwo }}</el-descriptions-item> |
| | | <el-descriptions-item label="走行速度(m/min)">{{ item.xspeed }}</el-descriptions-item> |
| | | <el-descriptions-item label="升降速度(m/min)">{{ item.yspeed }}</el-descriptions-item> |
| | | <el-descriptions-item label="叉牙速度(m/min)">{{ item.zspeed }}</el-descriptions-item> |
| | | <el-descriptions-item label="走行距离(Km)">{{ item.xdistance }}</el-descriptions-item> |
| | | <el-descriptions-item label="升降距离(Km)">{{ item.ydistance }}</el-descriptions-item> |
| | | <el-descriptions-item label="走行时长(H)">{{ item.xduration }}</el-descriptions-item> |
| | | <el-descriptions-item label="升降时长(H)">{{ item.yduration }}</el-descriptions-item> |
| | | <el-descriptions-item label="扩展数据">{{ item.extend }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </el-collapse-item> |
| | | </el-collapse> |
| | | </div> |
| | | <div style="display:flex; justify-content:flex-end; margin-top:8px;"> |
| | | <el-pagination |
| | | @current-change="handlePageChange" |
| | | @size-change="handleSizeChange" |
| | | :current-page="currentPage" |
| | | :page-size="pageSize" |
| | | :page-sizes="[10,20,50,100]" |
| | | layout="total, prev, pager, next" |
| | | :total="crnList.length"> |
| | | </el-pagination> |
| | | </div> |
| | | </div> |
| | | `, |
| | | props: ["param"], |
| | | data() { |
| | | return { |
| | | crnList: [], |
| | | activeNames: "", |
| | | searchCrnNo: "", |
| | | showControl: false, |
| | | controlParam: { |
| | | crnNo: "", |
| | | sourceLocNo: "", |
| | | targetLocNo: "", |
| | | station: 1, |
| | | }, |
| | | pageSize: 25, |
| | | currentPage: 1, |
| | | }; |
| | | }, |
| | | created() { |
| | | setInterval(() => { |
| | | this.getDualCrnStateInfo(); |
| | | }, 1000); |
| | | }, |
| | | computed: { |
| | | displayCrnList() { |
| | | const start = (this.currentPage - 1) * this.pageSize; |
| | | const end = start + this.pageSize; |
| | | return this.crnList.slice(start, end); |
| | | } |
| | | }, |
| | | watch: { |
| | | param: { |
| | | handler(newVal) { |
| | | if (newVal.crnNo != 0) { |
| | | this.activeNames = newVal.crnNo; |
| | | this.searchCrnNo = newVal.crnNo; |
| | | const idx = this.crnList.findIndex(i => i.crnNo == newVal.crnNo); |
| | | if (idx >= 0) { this.currentPage = Math.floor(idx / this.pageSize) + 1; } |
| | | } |
| | | }, |
| | | deep: true, |
| | | immediate: true, |
| | | }, |
| | | }, |
| | | methods: { |
| | | handlePageChange(page) { |
| | | this.currentPage = page; |
| | | }, |
| | | handleSizeChange(size) { |
| | | this.pageSize = size; |
| | | this.currentPage = 1; |
| | | }, |
| | | openControl() { |
| | | this.showControl = !this.showControl; |
| | | }, |
| | | getDualCrnStateInfo() { |
| | | if (this.$root.sendWs) { |
| | | this.$root.sendWs(JSON.stringify({ |
| | | "url": "/dualcrn/table/crn/state", |
| | | "data": {} |
| | | })); |
| | | } |
| | | }, |
| | | controlCommandTransport() { |
| | | let that = this; |
| | | $.ajax({ |
| | | url: baseUrl + "/dualcrn/command/take", |
| | | headers: { |
| | | token: localStorage.getItem("token"), |
| | | }, |
| | | contentType: "application/json", |
| | | method: "post", |
| | | data: JSON.stringify(that.controlParam), |
| | | success: (res) => { |
| | | if (res.code == 200) { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "success", |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "warning", |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | }, |
| | | controlCommandPickup() { |
| | | let that = this; |
| | | $.ajax({ |
| | | url: baseUrl + "/dualcrn/command/pick", |
| | | headers: { |
| | | token: localStorage.getItem("token"), |
| | | }, |
| | | contentType: "application/json", |
| | | method: "post", |
| | | data: JSON.stringify(that.controlParam), |
| | | success: (res) => { |
| | | if (res.code == 200) { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "success", |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "warning", |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | }, |
| | | controlCommandPutdown() { |
| | | let that = this; |
| | | $.ajax({ |
| | | url: baseUrl + "/dualcrn/command/put", |
| | | headers: { |
| | | token: localStorage.getItem("token"), |
| | | }, |
| | | contentType: "application/json", |
| | | method: "post", |
| | | data: JSON.stringify(that.controlParam), |
| | | success: (res) => { |
| | | if (res.code == 200) { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "success", |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "warning", |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | }, |
| | | controlCommandMove() { |
| | | let that = this; |
| | | $.ajax({ |
| | | url: baseUrl + "/dualcrn/command/move", |
| | | headers: { |
| | | token: localStorage.getItem("token"), |
| | | }, |
| | | contentType: "application/json", |
| | | method: "post", |
| | | data: JSON.stringify(that.controlParam), |
| | | success: (res) => { |
| | | if (res.code == 200) { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "success", |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "warning", |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | }, |
| | | controlCommandTaskComplete() { |
| | | let that = this; |
| | | $.ajax({ |
| | | url: baseUrl + "/dualcrn/command/taskComplete", |
| | | headers: { |
| | | token: localStorage.getItem("token"), |
| | | }, |
| | | contentType: "application/json", |
| | | method: "post", |
| | | data: JSON.stringify(that.controlParam), |
| | | success: (res) => { |
| | | if (res.code == 200) { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "success", |
| | | }); |
| | | } else { |
| | | that.$message({ |
| | | message: res.msg, |
| | | type: "warning", |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | }, |
| | | setDualCrnList(res) { |
| | | let that = this; |
| | | if (res.code == 200) { |
| | | let list = res.data; |
| | | if (that.searchCrnNo == "") { |
| | | that.crnList = list; |
| | | } else { |
| | | let tmp = []; |
| | | list.forEach((item) => { |
| | | if (item.crnNo == that.searchCrnNo) { |
| | | tmp.push(item); |
| | | } |
| | | }); |
| | | that.crnList = tmp; |
| | | that.currentPage = 1; |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | }); |
| | |
| | | <el-descriptions-item label="是否有物">{{ item.loading }}</el-descriptions-item> |
| | | <el-descriptions-item label="故障代码">{{ item.warnCode }}</el-descriptions-item> |
| | | <el-descriptions-item label="故障描述">{{ item.alarm }}</el-descriptions-item> |
| | | <el-descriptions-item label="扩展数据">{{ item.extend }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </el-collapse-item> |
| | | </el-collapse> |
| | |
| | | <el-tab-pane label="堆垛机" name="crn"> |
| | | <watch-crn-card ref="watchCrnCard" :param="crnParam"></watch-crn-card> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="双工位堆垛机" name="dualCrn"> |
| | | <watch-dual-crn-card ref="watchDualCrnCard" :param="dualCrnParam"></watch-dual-crn-card> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="输送站" name="devp"> |
| | | <devp-card ref="devpCard" :param="devpParam"></devp-card> |
| | | </el-tab-pane> |
| | |
| | | </el-tabs> |
| | | </div> |
| | | |
| | | <map-canvas :lev="currentLev" :crn-param="crnParam" :rgv-param="rgvParam" :devp-param="devpParam" @crn-click="openCrn" @station-click="openSite" style="width: 80%; height: 100vh;"></map-canvas> |
| | | <map-canvas :lev="currentLev" :crn-param="crnParam" :rgv-param="rgvParam" :devp-param="devpParam" @crn-click="openCrn" @dual-crn-click="openDualCrn" @station-click="openSite" style="width: 80%; height: 100vh;"></map-canvas> |
| | | |
| | | <div style="position: absolute;top: 15px;left: 50%;display: flex;"> |
| | | <div v-if="levList.length > 1" v-for="(lev,index) in levList" :key="index" style="margin-right: 10px;"> |
| | |
| | | </div> |
| | | |
| | | <script src="../../components/WatchCrnCard.js"></script> |
| | | <script src="../../components/WatchDualCrnCard.js"></script> |
| | | <script src="../../components/DevpCard.js"></script> |
| | | <script src="../../components/MapSettingCard.js"></script> |
| | | <script src="../../components/WatchRgvCard.js"></script> |
| | |
| | | crnParam: { |
| | | crnNo: 0 |
| | | }, |
| | | dualCrnParam: { |
| | | crnNo: 0 |
| | | }, |
| | | mapSettingParam: { |
| | | zoom: 70 |
| | | }, |
| | |
| | | rgvParam: { |
| | | rgvNo: 0 |
| | | }, |
| | | locMastData: []//库位数据 |
| | | locMastData: [],//库位数据 |
| | | wsReconnectTimer: null, |
| | | wsReconnectAttempts: 0, |
| | | wsReconnectBaseDelay: 1000, |
| | | wsReconnectMaxDelay: 15000 |
| | | }, |
| | | created() { |
| | | this.init() |
| | | }, |
| | | mounted() { |
| | | }, |
| | | beforeDestroy() { |
| | | if (this.wsReconnectTimer) { clearTimeout(this.wsReconnectTimer); this.wsReconnectTimer = null; } |
| | | if (ws && (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING)) { try { ws.close(); } catch (e) {} } |
| | | }, |
| | | watch: { |
| | | |
| | |
| | | }, |
| | | webSocketOnOpen() { |
| | | console.log("WebSocket连接成功"); |
| | | if (this.wsReconnectTimer) { clearTimeout(this.wsReconnectTimer); this.wsReconnectTimer = null; } |
| | | this.wsReconnectAttempts = 0; |
| | | this.getMap(); |
| | | }, |
| | | webSocketOnError() { |
| | | console.log("WebSocket连接发生错误"); |
| | | this.scheduleWsReconnect(); |
| | | }, |
| | | webSocketClose() { |
| | | console.log("WebSocket连接关闭"); |
| | | this.scheduleWsReconnect(); |
| | | }, |
| | | webSocketOnMessage(e) { |
| | | const result = JSON.parse(e.data); |
| | | if (result.url == "/crn/table/crn/state") { |
| | | if(this.$refs.watchCrnCard) { |
| | | this.$refs.watchCrnCard.setCrnList(JSON.parse(result.data)); |
| | | } |
| | | } else if (result.url == "/dualcrn/table/crn/state") { |
| | | if(this.$refs.watchDualCrnCard) { |
| | | this.$refs.watchDualCrnCard.setDualCrnList(JSON.parse(result.data)); |
| | | } |
| | | } else if (result.url == "/console/latest/data/station") { |
| | | if(this.$refs.devpCard) { |
| | |
| | | })) |
| | | }, |
| | | init() { |
| | | this.connectWs(); |
| | | |
| | | this.getSystemRunningStatus() //获取系统运行状态 |
| | | this.getLevList() //获取地图层级列表 |
| | | this.getLocMastData() //获取库位数据 |
| | | }, |
| | | connectWs() { |
| | | if (ws && (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING)) { return; } |
| | | ws = new WebSocket("ws://" + window.location.host + baseUrl + "/console/websocket"); |
| | | ws.onopen = this.webSocketOnOpen; |
| | | ws.onerror = this.webSocketOnError; |
| | | ws.onmessage = this.webSocketOnMessage; |
| | | ws.onclose = this.webSocketClose; |
| | | |
| | | this.getSystemRunningStatus() //获取系统运行状态 |
| | | this.getLevList() //获取地图层级列表 |
| | | this.getLocMastData() //获取库位数据 |
| | | }, |
| | | scheduleWsReconnect() { |
| | | if (this.wsReconnectTimer) { return; } |
| | | const attempt = this.wsReconnectAttempts + 1; |
| | | const jitter = Math.floor(Math.random() * 300); |
| | | const delay = Math.min(this.wsReconnectMaxDelay, this.wsReconnectBaseDelay * Math.pow(2, this.wsReconnectAttempts)) + jitter; |
| | | this.wsReconnectTimer = setTimeout(() => { |
| | | this.wsReconnectTimer = null; |
| | | this.wsReconnectAttempts = attempt; |
| | | this.connectWs(); |
| | | }, delay); |
| | | }, |
| | | getLevList() { |
| | | let that = this; |
| | |
| | | openCrn(id) { |
| | | this.crnParam.crnNo = id; |
| | | this.activateCard = 'crn'; |
| | | console.log(id); |
| | | }, |
| | | openDualCrn(id) { |
| | | this.dualCrnParam.crnNo = id; |
| | | this.activateCard = 'dualCrn'; |
| | | console.log(id); |
| | | |
| | | }, |
| | | openRgv(id) { |
| | | this.rgvParam.rgvNo = id; |