| package com.zy.asrs.wcs.core.utils; | 
|   | 
| import com.alibaba.fastjson.JSON; | 
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 
| import com.zy.asrs.framework.common.Cools; | 
| import com.zy.asrs.wcs.core.domain.dto.BasLiftLevOffsetDto; | 
| import com.zy.asrs.wcs.core.entity.BasLift; | 
| import com.zy.asrs.wcs.core.entity.ShuttleStandby; | 
| import com.zy.asrs.wcs.core.model.NavigateNode; | 
| import com.zy.asrs.wcs.core.model.enums.DeviceCtgType; | 
| import com.zy.asrs.wcs.core.model.enums.NavigationMapType; | 
| import com.zy.asrs.wcs.core.service.BasLiftService; | 
| import com.zy.asrs.wcs.core.service.ShuttleStandbyService; | 
| import com.zy.asrs.wcs.rcs.cache.SlaveConnection; | 
| import com.zy.asrs.wcs.rcs.entity.Device; | 
| import com.zy.asrs.wcs.rcs.model.enums.SlaveType; | 
| import com.zy.asrs.wcs.rcs.model.protocol.LiftProtocol; | 
| import com.zy.asrs.wcs.rcs.service.DeviceService; | 
| import com.zy.asrs.wcs.rcs.thread.LiftThread; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.stereotype.Service; | 
|   | 
| import java.util.List; | 
|   | 
| /** | 
|  * Created by vincent on 2023/10/16 | 
|  */ | 
| @Service | 
| public class LiftDispatcher { | 
|   | 
|     @Autowired | 
|     private DeviceService deviceService; | 
|     @Autowired | 
|     private BasLiftService basLiftService; | 
|     @Autowired | 
|     private ShuttleStandbyService shuttleStandbyService; | 
|     @Autowired | 
|     private NavigateUtils navigateUtils; | 
|   | 
|     /** | 
|      * 根据目标位置搜索提升机 | 
|      * transfer: 是否可换层 | 
|      */ | 
|     public LiftThread searchLift(String locNo, Long hostId, Boolean transfer) { | 
|         LiftThread recentLiftThread = null; | 
|         Integer finalDistance = Integer.MAX_VALUE; | 
|         List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>() | 
|                 .eq(Device::getDeviceType, DeviceCtgType.LIFT.val()) | 
|                 .eq(Device::getHostId, hostId) | 
|                 .eq(Device::getStatus, 1)); | 
|         for (Device device : list) { | 
|             LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, device.getId().intValue()); | 
|             if (liftThread == null) { | 
|                 continue; | 
|             } | 
|   | 
|             LiftProtocol liftProtocol = liftThread.getStatus(); | 
|             if (liftProtocol == null) { | 
|                 continue; | 
|             } | 
|   | 
|             if (transfer) { | 
|                 BasLift basLift = basLiftService.getOne(new LambdaQueryWrapper<BasLift>().eq(BasLift::getLiftNo, device.getDeviceNo()).eq(BasLift::getHostId, hostId)); | 
|                 if (basLift == null) { | 
|                     continue; | 
|                 } | 
|                 if (basLift.getTransfer() != 1) { | 
|                     continue;//提升机被设置成不可换层 | 
|                 } | 
|             } | 
|   | 
|             ShuttleStandby standby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>() | 
|                     .eq(ShuttleStandby::getDeviceId, device.getId()) | 
|                     .eq(ShuttleStandby::getDeviceLev, Utils.getLev(locNo)) | 
|                     .eq(ShuttleStandby::getStatus, 1)); | 
|             if (standby == null) { | 
|                 continue; | 
|             } | 
|   | 
|             String liftLocNo = Utils.getLocNo(Utils.getRow(standby.getDeviceStandbyLoc()), Utils.getBay(standby.getDeviceStandbyLoc()), Utils.getLev(locNo)); | 
|             List<NavigateNode> nodeList = navigateUtils.calc(locNo, liftLocNo, NavigationMapType.NONE.id, null); | 
|             if (nodeList == null) { | 
|                 continue; | 
|             } | 
|             Integer originPathAllDistance = navigateUtils.getOriginPathAllDistance(nodeList);//总距离 | 
|             if (originPathAllDistance < finalDistance) { | 
|                 finalDistance = originPathAllDistance; | 
|                 recentLiftThread = liftThread; | 
|             } | 
|         } | 
|   | 
|         return recentLiftThread; | 
|     } | 
|   | 
|     /** | 
|      * 根据目标位置搜索空闲提升机 | 
|      * transfer: 是否可换层 | 
|      */ | 
|     public LiftThread searchIdleLift(String locNo, Long hostId, Boolean transfer) { | 
|         LiftThread recentLiftThread = null; | 
|         Integer finalDistance = Integer.MAX_VALUE; | 
|         List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>() | 
|                 .eq(Device::getDeviceType, DeviceCtgType.LIFT.val()) | 
|                 .eq(Device::getHostId, hostId) | 
|                 .eq(Device::getStatus, 1)); | 
|         for (Device device : list) { | 
|             LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, device.getId().intValue()); | 
|             if (liftThread == null) { | 
|                 continue; | 
|             } | 
|   | 
|             LiftProtocol liftProtocol = liftThread.getStatus(); | 
|             if (liftProtocol == null) { | 
|                 continue; | 
|             } | 
|   | 
|             if (!liftThread.isIdle()) { | 
|                 continue; | 
|             } | 
|   | 
|             if (transfer) { | 
|                 BasLift basLift = basLiftService.getOne(new LambdaQueryWrapper<BasLift>().eq(BasLift::getLiftNo, device.getDeviceNo()).eq(BasLift::getHostId, hostId)); | 
|                 if (basLift == null) { | 
|                     continue; | 
|                 } | 
|                 if (basLift.getTransfer() != 1) { | 
|                     continue;//提升机被设置成不可换层 | 
|                 } | 
|             } | 
|   | 
|             ShuttleStandby standby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>() | 
|                     .eq(ShuttleStandby::getDeviceId, device.getId()) | 
|                     .eq(ShuttleStandby::getDeviceLev, Utils.getLev(locNo)) | 
|                     .eq(ShuttleStandby::getStatus, 1)); | 
|             if (standby == null) { | 
|                 continue; | 
|             } | 
|   | 
|             String liftLocNo = Utils.getLocNo(Utils.getRow(standby.getDeviceStandbyLoc()), Utils.getBay(standby.getDeviceStandbyLoc()), Utils.getLev(locNo)); | 
|             List<NavigateNode> nodeList = navigateUtils.calc(locNo, liftLocNo, NavigationMapType.NONE.id, null); | 
|             if (nodeList == null) { | 
|                 continue; | 
|             } | 
|             Integer originPathAllDistance = navigateUtils.getOriginPathAllDistance(nodeList);//总距离 | 
|             if (originPathAllDistance < finalDistance) { | 
|                 finalDistance = originPathAllDistance; | 
|                 recentLiftThread = liftThread; | 
|             } | 
|         } | 
|   | 
|         return recentLiftThread; | 
|     } | 
|   | 
|     /** | 
|      * 获取提升机位置 | 
|      */ | 
|     public String getLiftLocNo(LiftThread liftThread, Integer lev) { | 
|         Device device = liftThread.getDevice(); | 
|         ShuttleStandby standby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>() | 
|                 .eq(ShuttleStandby::getDeviceId, device.getId()) | 
|                 .eq(ShuttleStandby::getDeviceLev, lev) | 
|                 .eq(ShuttleStandby::getStatus, 1)); | 
|         if (standby == null) { | 
|             return null; | 
|         } | 
|   | 
|         String liftLocNo = Utils.getLocNo(Utils.getRow(standby.getDeviceLoc()), Utils.getBay(standby.getDeviceLoc()), lev); | 
|         return liftLocNo; | 
|     } | 
|   | 
|     /** | 
|      * 获取提升机待机位位置 | 
|      */ | 
|     public String getLiftStandByLocNo(LiftThread liftThread, Integer lev) { | 
|         Device device = liftThread.getDevice(); | 
|         ShuttleStandby standby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>() | 
|                 .eq(ShuttleStandby::getDeviceId, device.getId()) | 
|                 .eq(ShuttleStandby::getDeviceLev, lev) | 
|                 .eq(ShuttleStandby::getStatus, 1)); | 
|         if (standby == null) { | 
|             return null; | 
|         } | 
|   | 
|         String liftLocNo = Utils.getLocNo(Utils.getRow(standby.getDeviceStandbyLoc()), Utils.getBay(standby.getDeviceStandbyLoc()), lev); | 
|         return liftLocNo; | 
|     } | 
|   | 
|     /** | 
|      * 获取换层需要锁定的路径 | 
|      */ | 
|     public List<String> getLockPathByLocNo(LiftThread liftThread, Integer lev) { | 
|         Device device = liftThread.getDevice(); | 
|         ShuttleStandby standby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>() | 
|                 .eq(ShuttleStandby::getDeviceId, device.getId()) | 
|                 .eq(ShuttleStandby::getDeviceLev, lev) | 
|                 .eq(ShuttleStandby::getStatus, 1)); | 
|         if (standby == null) { | 
|             return null; | 
|         } | 
|   | 
|         return standby.getLockPath$(); | 
|     } | 
|   | 
|     public Integer getLiftLevOffset(Integer deviceId,Integer lev) { | 
|         BasLift basLift = basLiftService.getOne(new LambdaQueryWrapper<BasLift>().eq(BasLift::getDeviceId, deviceId)); | 
|         if (basLift != null) { | 
|             if(Cools.isEmpty(basLift.getLevOffset())) { | 
|                 return lev; | 
|             } | 
|             List<BasLiftLevOffsetDto> levOffsetDtos = JSON.parseArray(basLift.getLevOffset(), BasLiftLevOffsetDto.class); | 
|             for (BasLiftLevOffsetDto offsetDto : levOffsetDtos) { | 
|                 if(lev == offsetDto.getLogicLev()){ | 
|                     return offsetDto.getRealLev(); | 
|                 } | 
|             } | 
|         } | 
|         return lev; | 
|     } | 
|   | 
| } |