|  |  |  | 
|---|
|  |  |  | package com.zy.asrs.wcs.core.utils; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.model.enums.WorkZoneType; | 
|---|
|  |  |  | 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 { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public LiftThread queryLiftForTransport(String staNo) { | 
|---|
|  |  |  | WorkZoneType zoneType = WorkZoneType.query(staNo); | 
|---|
|  |  |  | LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, zoneType.liftNo); | 
|---|
|  |  |  | return liftThread; | 
|---|
|  |  |  | @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; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|