| | |
| | | package com.zy.asrs.wcs.core.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.zy.asrs.framework.common.Cools; |
| | | import com.zy.asrs.wcs.core.entity.Task; |
| | | import com.zy.asrs.framework.common.SnowflakeIdWorker; |
| | | import com.zy.asrs.wcs.core.entity.*; |
| | | import com.zy.asrs.wcs.core.kernel.AnalyzeService; |
| | | import com.zy.asrs.wcs.core.model.enums.DeviceCtgType; |
| | | import com.zy.asrs.wcs.core.model.enums.MotionStsType; |
| | | import com.zy.asrs.wcs.core.model.enums.TaskStsType; |
| | | import com.zy.asrs.wcs.core.service.TaskService; |
| | | import com.zy.asrs.wcs.core.service.*; |
| | | import com.zy.asrs.wcs.core.utils.ShuttleDispatcher; |
| | | import com.zy.asrs.wcs.core.utils.Utils; |
| | | import com.zy.asrs.wcs.rcs.News; |
| | | import com.zy.asrs.wcs.core.entity.Motion; |
| | | import com.zy.asrs.wcs.core.service.MotionService; |
| | | import com.zy.asrs.wcs.rcs.cache.SlaveConnection; |
| | | import com.zy.asrs.wcs.rcs.entity.Device; |
| | | import com.zy.asrs.wcs.rcs.entity.DeviceType; |
| | | import com.zy.asrs.wcs.rcs.model.enums.ShuttleProtocolStatusType; |
| | | import com.zy.asrs.wcs.rcs.model.enums.SlaveType; |
| | | import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol; |
| | | import com.zy.asrs.wcs.rcs.model.protocol.StaProtocol; |
| | | import com.zy.asrs.wcs.rcs.service.DeviceService; |
| | | import com.zy.asrs.wcs.rcs.service.DeviceTypeService; |
| | | import com.zy.asrs.wcs.rcs.thread.DevpThread; |
| | | import com.zy.asrs.wcs.rcs.thread.ShuttleThread; |
| | | import com.zy.asrs.wcs.system.entity.Dict; |
| | | import com.zy.asrs.wcs.system.service.DictService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | |
| | | private AnalyzeService analyzeService; |
| | | @Autowired |
| | | private MotionService motionService; |
| | | @Autowired |
| | | private DeviceService deviceService; |
| | | @Autowired |
| | | private DeviceTypeService deviceTypeService; |
| | | @Autowired |
| | | private LocCtgService locCtgService; |
| | | @Autowired |
| | | private LocService locService; |
| | | @Autowired |
| | | private SnowflakeIdWorker snowflakeIdWorker; |
| | | @Autowired |
| | | private TaskCtgService taskCtgService; |
| | | @Autowired |
| | | private DictService dictService; |
| | | @Autowired |
| | | private ShuttleDispatcher shuttleDispatcher; |
| | | |
| | | /** |
| | | * 组托 |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 四向穿梭车电量检测 ===>> 发起充电 |
| | | */ |
| | | public synchronized void loopShuttleCharge() { |
| | | // 获取充电桩库位类型 |
| | | LocCtg locCtg = locCtgService.getOne(new LambdaQueryWrapper<LocCtg>() |
| | | .eq(LocCtg::getFlag, "CHARGE") |
| | | .eq(LocCtg::getStatus, 1)); |
| | | if (locCtg == null) { |
| | | return; |
| | | } |
| | | |
| | | //获取充电任务类型 |
| | | TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() |
| | | .eq(TaskCtg::getFlag, "CHARGE") |
| | | .eq(TaskCtg::getStatus, 1)); |
| | | if (taskCtg == null) { |
| | | return; |
| | | } |
| | | |
| | | DeviceType deviceType = deviceTypeService.getOne(new LambdaQueryWrapper<DeviceType>() |
| | | .eq(DeviceType::getFlag, String.valueOf(SlaveType.Shuttle)) |
| | | .eq(DeviceType::getStatus, 1)); |
| | | if (deviceType == null) { |
| | | return; |
| | | } |
| | | |
| | | List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>() |
| | | .eq(Device::getDeviceType, deviceType.getId()) |
| | | .eq(Device::getStatus, 1)); |
| | | for (Device device : list) { |
| | | //获取四向穿梭车线程 |
| | | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); |
| | | if (shuttleThread == null) { |
| | | continue; |
| | | } |
| | | |
| | | ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); |
| | | if (shuttleProtocol == null) { |
| | | continue; |
| | | } |
| | | |
| | | if (!shuttleProtocol.getProtocolStatusType().equals(ShuttleProtocolStatusType.IDLE)) { |
| | | continue; |
| | | } |
| | | |
| | | String currentLocNo = shuttleProtocol.getCurrentLocNo(); |
| | | int lev = Utils.getLev(currentLocNo);//获取小车楼层 |
| | | //搜索小车当前楼层充电桩 |
| | | ArrayList<Loc> allChargeLoc = new ArrayList<>(); |
| | | List<Loc> list1 = locService.list(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getLocCtg, locCtg.getId()) |
| | | .eq(Loc::getStatus, 1) |
| | | .eq(Loc::getLev, lev)); |
| | | if (!list1.isEmpty()) { |
| | | allChargeLoc.addAll(list1); |
| | | } |
| | | |
| | | //搜索其他楼层充电桩 |
| | | List<Loc> list2 = locService.list(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getLocCtg, locCtg.getId()) |
| | | .eq(Loc::getStatus, 1) |
| | | .notIn(Loc::getLev, lev)); |
| | | if (!list2.isEmpty()) { |
| | | allChargeLoc.addAll(list2); |
| | | } |
| | | |
| | | //没有找到充电桩 |
| | | if (allChargeLoc.isEmpty()) { |
| | | continue; |
| | | } |
| | | |
| | | //选择空闲充电桩 |
| | | Loc chargeLoc = null; |
| | | for (Loc loc : allChargeLoc) { |
| | | // 判断充电位是否被占用(车辆位置) |
| | | if (Utils.hasShuttleInLoc(loc.getLocNo(), device.getId())) { |
| | | continue; |
| | | } |
| | | |
| | | // 盘点充电位是否存在任务档 |
| | | List<Task> tasks = taskService.hasChargeInLoc(loc.getLocNo()); |
| | | if (!tasks.isEmpty()) { |
| | | continue; |
| | | } |
| | | |
| | | chargeLoc = loc; |
| | | break; |
| | | } |
| | | |
| | | if (chargeLoc == null) { |
| | | continue;//未找到充电桩 |
| | | } |
| | | |
| | | if (motionService.count(new LambdaQueryWrapper<Motion>() |
| | | .eq(Motion::getDeviceCtg, DeviceCtgType.SHUTTLE.val()) |
| | | .eq(Motion::getDevice, device.getDeviceNo()) |
| | | .eq(Motion::getMotionSts, MotionStsType.EXECUTING.val())) > 0) { |
| | | continue; |
| | | } |
| | | |
| | | //判断当前小车是否满足需要充电要求 |
| | | if (!shuttleThread.isRequireCharge()) { |
| | | continue; |
| | | } |
| | | |
| | | Task taskCharge = taskService.selectChargeWorking(Integer.valueOf(device.getDeviceNo())); |
| | | if (taskCharge != null) {//已有充电任务 |
| | | continue; |
| | | } |
| | | |
| | | String chargeLocNo = chargeLoc.getLocNo(); |
| | | Task task = new Task(); |
| | | task.setUuid(String.valueOf(snowflakeIdWorker.nextId())); |
| | | task.setTaskNo(String.valueOf(Utils.getTaskNo("CHARGE"))); |
| | | task.setTaskSts(TaskStsType.NEW_CHARGE.getId()); |
| | | task.setTaskCtg(taskCtg.getId()); |
| | | task.setPriority(10); |
| | | task.setOriginSite(null); |
| | | task.setOriginLoc(null); |
| | | task.setDestSite(null); |
| | | task.setDestLoc(chargeLocNo); |
| | | task.setIoTime(new Date()); |
| | | task.setStartTime(new Date()); |
| | | task.setHostId(device.getHostId()); |
| | | task.setStatus(1); |
| | | task.setMemo("charge"); |
| | | task.setShuttleNo(Integer.valueOf(device.getDeviceNo())); |
| | | |
| | | // generate motion list |
| | | List<Motion> motionList = analyzeService.generateChargeMotion(task); |
| | | if (Cools.isEmpty(motionList)) { |
| | | News.error("保存{}号四向穿梭车充电任务失败!!!", device.getDeviceNo()); |
| | | continue; |
| | | } |
| | | motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo())); |
| | | |
| | | task.setTaskSts(TaskStsType.ANALYZE_CHARGE.sts); |
| | | if (!taskService.save(task)) { |
| | | News.error("保存{}号四向穿梭车充电任务失败!!!", device.getDeviceNo()); |
| | | continue; |
| | | } |
| | | |
| | | News.info("保存{}号四向穿梭车充电任务成功!!!", device.getDeviceNo()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 四向穿梭车电量检测 ===>> 满电后回到待机位 |
| | | */ |
| | | public synchronized void loopShuttleToStandbyCauseCharge() { |
| | | Integer enoughPower = 90; |
| | | Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>() |
| | | .eq(Dict::getFlag, "chargeMaxValue") |
| | | .eq(Dict::getStatus, 1)); |
| | | if (dict != null) { |
| | | enoughPower = Integer.parseInt(dict.getValue()); |
| | | } |
| | | |
| | | //获取迁移任务类型 |
| | | TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() |
| | | .eq(TaskCtg::getFlag, "MOVE") |
| | | .eq(TaskCtg::getStatus, 1)); |
| | | if (taskCtg == null) { |
| | | return; |
| | | } |
| | | |
| | | DeviceType deviceType = deviceTypeService.getOne(new LambdaQueryWrapper<DeviceType>() |
| | | .eq(DeviceType::getFlag, String.valueOf(SlaveType.Shuttle)) |
| | | .eq(DeviceType::getStatus, 1)); |
| | | if (deviceType == null) { |
| | | return; |
| | | } |
| | | |
| | | List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>() |
| | | .eq(Device::getDeviceType, deviceType.getId()) |
| | | .eq(Device::getStatus, 1)); |
| | | for (Device device : list) { |
| | | //获取四向穿梭车线程 |
| | | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); |
| | | if (shuttleThread == null) { |
| | | continue; |
| | | } |
| | | |
| | | if (!shuttleThread.isCharging()) { |
| | | continue; |
| | | } |
| | | |
| | | if (!shuttleThread.isChargingCompleted()) { |
| | | continue; |
| | | } |
| | | |
| | | //查找充电任务 |
| | | Task chargeTask = taskService.getOne(new LambdaQueryWrapper<Task>() |
| | | .eq(Task::getTaskSts, TaskStsType.CHARGE_WORKING.sts) |
| | | .eq(Task::getShuttleNo, device.getDeviceNo())); |
| | | if (chargeTask == null) { |
| | | continue; |
| | | } |
| | | |
| | | //充电完成 |
| | | // 已有迁移任务 |
| | | if (taskService.selectMoveWorking(Integer.valueOf(device.getDeviceNo())) != null) { |
| | | continue; |
| | | } |
| | | |
| | | //获取避让位置 |
| | | String standByLocNo = shuttleDispatcher.searchStandByLocNo(Integer.valueOf(device.getDeviceNo()), device.getHostId(), shuttleThread.getStatus().getCurrentLocNo()); |
| | | |
| | | Task task = new Task(); |
| | | task.setUuid(String.valueOf(snowflakeIdWorker.nextId())); |
| | | task.setTaskNo(String.valueOf(Utils.getTaskNo("MOVE"))); |
| | | task.setTaskSts(TaskStsType.NEW_MOVE.getId()); |
| | | task.setTaskCtg(taskCtg.getId()); |
| | | task.setPriority(10); |
| | | task.setOriginSite(null); |
| | | task.setOriginLoc(null); |
| | | task.setDestSite(null); |
| | | task.setDestLoc(standByLocNo); // 避让位置 |
| | | task.setIoTime(new Date()); |
| | | task.setStartTime(new Date()); |
| | | task.setHostId(device.getHostId()); |
| | | task.setStatus(1); |
| | | task.setMemo("charge"); |
| | | task.setShuttleNo(Integer.valueOf(device.getDeviceNo())); |
| | | |
| | | // generate motion list |
| | | List<Motion> motionList = analyzeService.generateShuttleChargeWrkComplete(task); |
| | | if (Cools.isEmpty(motionList)) { |
| | | News.error("保存{}号四向穿梭车迁移任务失败!!!", device.getDeviceNo()); |
| | | continue; |
| | | } |
| | | motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo())); |
| | | |
| | | task.setTaskSts(TaskStsType.ANALYZE_MOVE.sts); |
| | | |
| | | if (!taskService.save(task)) { |
| | | News.error("保存{}号四向穿梭车迁移任务失败!!!", device.getDeviceNo()); |
| | | continue; |
| | | } |
| | | |
| | | chargeTask.setTaskSts(TaskStsType.COMPLETE_CHARGE.sts); |
| | | chargeTask.setIoTime(new Date()); |
| | | taskService.updateById(chargeTask); |
| | | } |
| | | } |
| | | |
| | | } |