| | |
| | | private static final int TASK_AREA_LENGTH = 48; |
| | | private static final int TASK_AREA_SLOT_SIZE = 12; |
| | | private static final int TASK_AREA_SLOT_COUNT = 3; |
| | | private static final String[] CONVEYOR_COMMON_ALARM_MESSAGES = { |
| | | "急停", |
| | | "低位断路器断开", |
| | | "低位变频器故障", |
| | | "输送运行超时", |
| | | "顶升运行超时", |
| | | "申请任务超时", |
| | | "托盘突出报警", |
| | | "任务运行超时", |
| | | "FWD旋转限位报警", |
| | | "REV旋转限位报警", |
| | | "扫码检验异常", |
| | | "安全门打开报警", |
| | | "任务重复报警", |
| | | "入站过程中前置条件异常", |
| | | "入站前置条件等待超时", |
| | | "出站过程中前置条件异常", |
| | | "出站前置条件等待超时", |
| | | "高位断路器断开", |
| | | "高位变频器故障", |
| | | "顶升限位信号异常", |
| | | "入站运行中,上站同步运行请求消失", |
| | | "出站完成后,仍然检测到托盘", |
| | | "入站完成后,没有检测到托盘", |
| | | "下站站号异常", |
| | | "路径查询异常" |
| | | }; |
| | | |
| | | private List<ZyStationStatusEntity> statusList; |
| | | private List<StationObjModel> barcodeOriginList; |
| | | private List<StationObjModel> inStationOriginList; |
| | | private SiemensS7Net siemensNet; |
| | | private DeviceConfig deviceConfig; |
| | | private RedisUtil redisUtil; |
| | |
| | | statusList.sort(Comparator.comparing(ZyStationStatusEntity::getStationId)); |
| | | } |
| | | barcodeOriginList = basDevp.getBarcodeStationList$(); |
| | | inStationOriginList = sortStationObjModelsByStationId(basDevp.getInStationList$()); |
| | | } |
| | | |
| | | if (siemensNet == null) { |
| | |
| | | statusEntity.setPalletHeight(palletHeight);//高低信号 |
| | | |
| | | statusEntity.setError(0);//默认无报警 |
| | | statusEntity.setErrorMsg(""); |
| | | |
| | | statusEntity.setTaskWriteIdx((int) siemensNet.getByteTransform().TransInt16(result.Content, i * 10 + 8));//任务可写区 |
| | | fillTaskBufferStatus(taskBufferRaw, i, statusEntity); |
| | |
| | | } |
| | | } |
| | | |
| | | // 报警信息 |
| | | // 条码站报警信息 |
| | | OperateResultExOne<byte[]> result4 = siemensNet.Read("DB103.2", (short) (barcodeOriginList.size() * 2)); |
| | | if (result4.IsSuccess) { |
| | | for (int i = 0; i < barcodeOriginList.size(); i++) { |
| | |
| | | sb.append("扫码异常;"); |
| | | } |
| | | |
| | | if(sb.length() > 0) { |
| | | barcodeEntity.setError(1); |
| | | }else { |
| | | barcodeEntity.setError(0); |
| | | applyAlarmMessage(barcodeEntity, sb.toString()); |
| | | } |
| | | } |
| | | |
| | | // 输送站点通用报警信息 |
| | | OperateResultExOne<byte[]> result5 = siemensNet.Read("DB25.0", (short) (statusList.size() * 4)); |
| | | if (result5.IsSuccess) { |
| | | for (int i = 0; i < statusList.size(); i++) { |
| | | ZyStationStatusEntity statusEntity = statusList.get(i); // 站点编号 |
| | | boolean[] status1 = siemensNet.getByteTransform().TransBool(result5.Content, i * 4, 1); |
| | | boolean[] status2 = siemensNet.getByteTransform().TransBool(result5.Content, i * 4 + 1, 1); |
| | | boolean[] status3 = siemensNet.getByteTransform().TransBool(result5.Content, i * 4 + 2, 1); |
| | | boolean[] status4 = siemensNet.getByteTransform().TransBool(result5.Content, i * 4 + 3, 1); |
| | | |
| | | String alarmMsg = buildConveyorCommonAlarmMessage(status1, status2, status3, status4); |
| | | applyAlarmMessage(statusEntity, mergeAlarmMessages(statusEntity.getErrorMsg(), alarmMsg)); |
| | | } |
| | | } |
| | | |
| | | // 出入库模式 |
| | | OperateResultExOne<byte[]> result6 = siemensNet.Read("DB167.2", (short) (inStationOriginList.size() * 2)); |
| | | if (result6.IsSuccess) { |
| | | for (int i = 0; i < inStationOriginList.size(); i++) { |
| | | ZyStationStatusEntity inStationEntity = findStatusEntityByInStationIdx(i); |
| | | if (inStationEntity == null) { |
| | | continue; |
| | | } |
| | | barcodeEntity.setErrorMsg(sb.toString()); |
| | | Integer ioMode = normalizeIoMode((int) siemensNet.getByteTransform().TransInt16(result6.Content, i * 2)); |
| | | inStationEntity.setIoMode(ioMode); |
| | | } |
| | | } |
| | | |
| | |
| | | return commandResponse; |
| | | } |
| | | |
| | | if (isDuplicateStationCommand(statusEntity, command)) { |
| | | log.info("输送线命令重复,已跳过当前站点命令。任务号={},站点号={},目标站={},taskWriteIdx={},currentTaskNo={},currentTargetStaNo={}", |
| | | command.getTaskNo(), |
| | | command.getStationId(), |
| | | command.getTargetStaNo(), |
| | | taskWriteIdx, |
| | | statusEntity == null ? null : statusEntity.getTaskNo(), |
| | | statusEntity == null ? null : statusEntity.getTargetStaNo()); |
| | | commandResponse.setResult(true); |
| | | commandResponse.setMessage("命令重复,已跳过下发"); |
| | | return commandResponse; |
| | | } |
| | | |
| | | Integer duplicateSlotIdx = findDuplicateTaskAreaSlot(stationIdx, command); |
| | | if (duplicateSlotIdx != null) { |
| | | log.info("输送线命令重复,已跳过任务写入区重复命令。任务号={},站点号={},目标站={},taskWriteIdx={},duplicateSlotIdx={}", |
| | | command.getTaskNo(), |
| | | command.getStationId(), |
| | | command.getTargetStaNo(), |
| | | taskWriteIdx, |
| | | duplicateSlotIdx); |
| | | commandResponse.setResult(true); |
| | | commandResponse.setMessage("任务区已有相同命令,已跳过下发"); |
| | | return commandResponse; |
| | | } |
| | | |
| | | int useTaskWriteIdx = getTaskWriteIdx(stationIdx, taskWriteIdx); |
| | | if (useTaskWriteIdx == -1) { |
| | | commandResponse.setMessage("命令下发超时,无法找到可用下发区域"); |
| | |
| | | |
| | | log.info("写入输送线命令成功。任务号={},站点数据={}", command.getTaskNo(), JSON.toJSON(command)); |
| | | commandResponse.setResult(true); |
| | | return commandResponse; |
| | | } |
| | | |
| | | @Override |
| | | public CommandResponse clearTaskBufferSlot(Integer deviceNo, Integer stationId, Integer slotIdx) { |
| | | CommandResponse commandResponse = new CommandResponse(false); |
| | | if (stationId == null) { |
| | | commandResponse.setMessage("站点号为空"); |
| | | return commandResponse; |
| | | } |
| | | if (slotIdx == null || slotIdx <= 0 || slotIdx > TASK_AREA_SLOT_COUNT) { |
| | | commandResponse.setMessage("缓存区槽位无效"); |
| | | return commandResponse; |
| | | } |
| | | |
| | | getStatus(deviceNo); |
| | | |
| | | int stationIdx = findIndex(stationId); |
| | | if (stationIdx < 0) { |
| | | commandResponse.setMessage("未找到站点状态"); |
| | | return commandResponse; |
| | | } |
| | | |
| | | int slotBaseOffset = stationIdx * TASK_AREA_LENGTH + slotIdx * TASK_AREA_SLOT_SIZE; |
| | | CommandResponse clearTaskNo = sendOriginCommand("DB13." + slotBaseOffset, new short[]{0, 0}); |
| | | if (clearTaskNo == null || !Boolean.TRUE.equals(clearTaskNo.getResult())) { |
| | | commandResponse.setMessage(clearTaskNo == null ? "清空任务号失败" : clearTaskNo.getMessage()); |
| | | return commandResponse; |
| | | } |
| | | |
| | | CommandResponse clearTarget = sendOriginCommand("DB13." + (slotBaseOffset + 6), new short[]{0}); |
| | | if (clearTarget == null || !Boolean.TRUE.equals(clearTarget.getResult())) { |
| | | commandResponse.setMessage(clearTarget == null ? "清空目标站失败" : clearTarget.getMessage()); |
| | | return commandResponse; |
| | | } |
| | | |
| | | commandResponse.setResult(true); |
| | | commandResponse.setMessage("缓存区槽位清理成功"); |
| | | return commandResponse; |
| | | } |
| | | |
| | |
| | | return null; |
| | | } |
| | | |
| | | private ZyStationStatusEntity findStatusEntityByInStationIdx(Integer idx) { |
| | | Integer stationId = findInStationIdByOrder(inStationOriginList, idx); |
| | | |
| | | for (ZyStationStatusEntity zyStationStatusEntity : statusList) { |
| | | if(zyStationStatusEntity.getStationId().equals(stationId)) { |
| | | return zyStationStatusEntity; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private int getTaskWriteIdx(int stationIdx, Integer taskWriteIdx) { |
| | | int useIdx = -1; |
| | | if (stationIdx < 0 || taskWriteIdx == null || taskWriteIdx <= 0) { |
| | |
| | | } |
| | | } |
| | | return useIdx; |
| | | } |
| | | |
| | | private boolean isDuplicateStationCommand(ZyStationStatusEntity statusEntity, StationCommand command) { |
| | | if (statusEntity == null || command == null) { |
| | | return false; |
| | | } |
| | | return command.getTaskNo() != null |
| | | && command.getTargetStaNo() != null |
| | | && command.getTaskNo().equals(statusEntity.getTaskNo()) |
| | | && command.getTargetStaNo().equals(statusEntity.getTargetStaNo()); |
| | | } |
| | | |
| | | private Integer findDuplicateTaskAreaSlot(int stationIdx, StationCommand command) { |
| | | if (stationIdx < 0 || command == null || command.getTaskNo() == null || command.getTargetStaNo() == null) { |
| | | return null; |
| | | } |
| | | OperateResultExOne<byte[]> resultTask = siemensNet.Read("DB13." + (stationIdx * TASK_AREA_LENGTH), (short) TASK_AREA_LENGTH); |
| | | if (!resultTask.IsSuccess || resultTask.Content == null) { |
| | | return null; |
| | | } |
| | | for (int slotIdx = 1; slotIdx <= TASK_AREA_SLOT_COUNT; slotIdx++) { |
| | | int offset = slotIdx * TASK_AREA_SLOT_SIZE; |
| | | int taskNo = siemensNet.getByteTransform().TransInt32(resultTask.Content, offset); |
| | | int targetPoint = siemensNet.getByteTransform().TransInt16(resultTask.Content, offset + 6); |
| | | if (command.getTaskNo().equals(taskNo) |
| | | && command.getTargetStaNo().equals(targetPoint)) { |
| | | return slotIdx; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private byte[] readTaskBufferRaw() { |
| | |
| | | return -1; |
| | | } |
| | | |
| | | static String buildConveyorCommonAlarmMessage(boolean[] status1, boolean[] status2, boolean[] status3, boolean[] status4) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | appendConveyorCommonAlarmMessages(sb, status1, 0); |
| | | appendConveyorCommonAlarmMessages(sb, status2, 8); |
| | | appendConveyorCommonAlarmMessages(sb, status3, 16); |
| | | appendConveyorCommonAlarmMessages(sb, status4, 24); |
| | | return sb.toString(); |
| | | } |
| | | |
| | | static String mergeAlarmMessages(String currentMsg, String appendMsg) { |
| | | String current = currentMsg == null ? "" : currentMsg; |
| | | String append = appendMsg == null ? "" : appendMsg; |
| | | if (append.isEmpty()) { |
| | | return current; |
| | | } |
| | | if (current.isEmpty()) { |
| | | return append; |
| | | } |
| | | if (!current.endsWith(";")) { |
| | | current += ";"; |
| | | } |
| | | return current + append; |
| | | } |
| | | |
| | | static Integer normalizeIoMode(Integer rawMode) { |
| | | if (rawMode == null) { |
| | | return null; |
| | | } |
| | | if (rawMode == 1 || rawMode == 2) { |
| | | return rawMode; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | static Integer findInStationIdByOrder(List<StationObjModel> inStationOriginList, Integer orderIdx) { |
| | | if (inStationOriginList == null || orderIdx == null || orderIdx < 0 || orderIdx >= inStationOriginList.size()) { |
| | | return null; |
| | | } |
| | | StationObjModel stationObjModel = inStationOriginList.get(orderIdx); |
| | | return stationObjModel == null ? null : stationObjModel.getStationId(); |
| | | } |
| | | |
| | | static List<StationObjModel> sortStationObjModelsByStationId(List<StationObjModel> stationObjModels) { |
| | | if (stationObjModels == null) { |
| | | return Collections.emptyList(); |
| | | } |
| | | stationObjModels.sort(Comparator.comparing(StationObjModel::getStationId, Comparator.nullsLast(Integer::compareTo))); |
| | | return stationObjModels; |
| | | } |
| | | |
| | | private static void appendConveyorCommonAlarmMessages(StringBuilder sb, boolean[] status, int startIdx) { |
| | | if (status == null) { |
| | | return; |
| | | } |
| | | int limit = Math.min(status.length, 8); |
| | | for (int i = 0; i < limit; i++) { |
| | | int alarmIdx = startIdx + i; |
| | | if (!status[i] || alarmIdx >= CONVEYOR_COMMON_ALARM_MESSAGES.length) { |
| | | continue; |
| | | } |
| | | sb.append(CONVEYOR_COMMON_ALARM_MESSAGES[alarmIdx]).append(";"); |
| | | } |
| | | } |
| | | |
| | | private static void applyAlarmMessage(ZyStationStatusEntity statusEntity, String alarmMsg) { |
| | | if (statusEntity == null) { |
| | | return; |
| | | } |
| | | String message = alarmMsg == null ? "" : alarmMsg; |
| | | statusEntity.setError(message.isEmpty() ? 0 : 1); |
| | | statusEntity.setErrorMsg(message); |
| | | } |
| | | |
| | | } |