| | |
| | | import com.zy.core.model.CommandResponse; |
| | | import com.zy.core.model.StationObjModel; |
| | | import com.zy.core.model.command.StationCommand; |
| | | import com.zy.core.model.protocol.StationTaskBufferItem; |
| | | import com.zy.core.network.api.ZyStationConnectApi; |
| | | import com.zy.core.network.entity.ZyStationStatusEntity; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.text.MessageFormat; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.Comparator; |
| | | import java.util.Date; |
| | |
| | | */ |
| | | @Slf4j |
| | | public class ZyStationV4RealConnect implements ZyStationConnectApi { |
| | | |
| | | 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 List<ZyStationStatusEntity> statusList; |
| | | private List<StationObjModel> barcodeOriginList; |
| | |
| | | statusEntity.setError(0);//默认无报警 |
| | | |
| | | statusEntity.setTaskWriteIdx((int) siemensNet.getByteTransform().TransInt16(result.Content, i * 10 + 8));//任务可写区 |
| | | fillTaskBufferStatus(i, statusEntity); |
| | | } |
| | | } |
| | | |
| | |
| | | return commandResponse; |
| | | } |
| | | |
| | | int taskWriteIdx = getTaskWriteIdx(command.getStationId()); |
| | | if (taskWriteIdx == -1) { |
| | | getStatus(deviceNo); |
| | | |
| | | int stationIdx = findIndex(command.getStationId()); |
| | | if (stationIdx == -1) { |
| | | commandResponse.setMessage("命令下发失败,未找到站点状态"); |
| | | return commandResponse; |
| | | } |
| | | |
| | | ZyStationStatusEntity statusEntity = statusList.get(stationIdx); |
| | | Integer taskWriteIdx = statusEntity == null ? null : statusEntity.getTaskWriteIdx(); |
| | | if (taskWriteIdx == null || taskWriteIdx <= 0) { |
| | | commandResponse.setMessage("命令下发失败,当前无可用任务写入区"); |
| | | 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("命令下发超时,无法找到可用下发区域"); |
| | | return commandResponse; |
| | | } |
| | | |
| | | int stationIdx = findIndex(command.getStationId()); |
| | | int taskBaseOffset = stationIdx * TASK_AREA_LENGTH + (useTaskWriteIdx * TASK_AREA_SLOT_SIZE); |
| | | |
| | | short[] data = new short[2]; |
| | | data[0] = (short) 0; |
| | | data[1] = command.getTargetStaNo().shortValue(); |
| | | |
| | | OperateResult writeTaskNo = siemensNet.Write("DB13." + (stationIdx * 48 + (taskWriteIdx * 12)), command.getTaskNo()); |
| | | OperateResult writeTaskNo = siemensNet.Write("DB13." + taskBaseOffset, command.getTaskNo()); |
| | | if (!writeTaskNo.IsSuccess) { |
| | | log.error("写入输送线命令失败。站点编号={},站点数据={}", command.getTaskNo(), JSON.toJSON(command)); |
| | | commandResponse.setResult(false); |
| | |
| | | return commandResponse; |
| | | } |
| | | |
| | | OperateResult writeData = siemensNet.Write("DB13." + (stationIdx * 48 + (taskWriteIdx * 12 + 4)), data); |
| | | if (!writeData.IsSuccess) { |
| | | OperateResult writeTarget = siemensNet.Write("DB13." + (taskBaseOffset + 6), command.getTargetStaNo().shortValue()); |
| | | if (!writeTarget.IsSuccess) { |
| | | log.error("写入输送线命令失败。站点编号={},站点数据={}", command.getTaskNo(), JSON.toJSON(command)); |
| | | commandResponse.setResult(false); |
| | | commandResponse.setMessage("命令下发失败,写入数据区域失败"); |
| | | commandResponse.setMessage("命令下发失败,写入目标设备号失败"); |
| | | return commandResponse; |
| | | } |
| | | |
| | |
| | | return null; |
| | | } |
| | | |
| | | private int getTaskWriteIdx(int stationId) { |
| | | private int getTaskWriteIdx(int stationIdx, Integer taskWriteIdx) { |
| | | int useIdx = -1; |
| | | |
| | | int stationIdx = findIndex(stationId); |
| | | if (stationIdx != -1) { |
| | | ZyStationStatusEntity statusEntity = statusList.get(stationIdx); |
| | | |
| | | Integer taskWriteIdx = statusEntity.getTaskWriteIdx(); |
| | | if (taskWriteIdx > 0) { |
| | | OperateResultExOne<byte[]> resultTask = siemensNet.Read("DB13." + (stationId * 48), (short) 48); |
| | | if (resultTask.IsSuccess) { |
| | | int taskNo = siemensNet.getByteTransform().TransInt32(resultTask.Content, taskWriteIdx * 12); |
| | | int startPoint = siemensNet.getByteTransform().TransInt16(resultTask.Content, taskWriteIdx * 12 + 4); |
| | | int targetPoint = siemensNet.getByteTransform().TransInt16(resultTask.Content, taskWriteIdx * 12 + 6); |
| | | if (taskNo == 0 && startPoint == 0 && targetPoint == 0) { |
| | | useIdx = taskWriteIdx; |
| | | } |
| | | } |
| | | if (stationIdx < 0 || taskWriteIdx == null || taskWriteIdx <= 0) { |
| | | return useIdx; |
| | | } |
| | | OperateResultExOne<byte[]> resultTask = siemensNet.Read("DB13." + (stationIdx * TASK_AREA_LENGTH), (short) TASK_AREA_LENGTH); |
| | | if (resultTask.IsSuccess) { |
| | | int taskNo = siemensNet.getByteTransform().TransInt32(resultTask.Content, taskWriteIdx * TASK_AREA_SLOT_SIZE); |
| | | int targetPoint = siemensNet.getByteTransform().TransInt16(resultTask.Content, taskWriteIdx * TASK_AREA_SLOT_SIZE + 6); |
| | | if (taskNo == 0 && targetPoint == 0) { |
| | | useIdx = taskWriteIdx; |
| | | } |
| | | } |
| | | |
| | | 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 void fillTaskBufferStatus(int stationIdx, ZyStationStatusEntity statusEntity) { |
| | | if (statusEntity == null || stationIdx < 0) { |
| | | return; |
| | | } |
| | | List<StationTaskBufferItem> itemList = new ArrayList<>(); |
| | | OperateResultExOne<byte[]> resultTask = siemensNet.Read("DB13." + (stationIdx * TASK_AREA_LENGTH), (short) TASK_AREA_LENGTH); |
| | | if (resultTask.IsSuccess && resultTask.Content != 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); |
| | | StationTaskBufferItem item = new StationTaskBufferItem(); |
| | | item.setSlotIdx(slotIdx); |
| | | item.setTaskNo(taskNo); |
| | | item.setTargetStaNo(targetPoint); |
| | | itemList.add(item); |
| | | } |
| | | } |
| | | statusEntity.setTaskBufferItems(itemList); |
| | | } |
| | | |
| | | private int findIndex(Integer stationId) { |
| | | for (int i = 0; i < statusList.size(); i++) { |
| | | ZyStationStatusEntity statusEntity = statusList.get(i); |