diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/AutoCreateInst.java b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/AutoCreateInst.java new file mode 100644 index 0000000..c1b4fda --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/AutoCreateInst.java @@ -0,0 +1,130 @@ +package org.nl.modules.quartz.task; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.DeviceAppService; +import org.nl.acs.opc.DeviceAppServiceImpl; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.wql.util.SpringContextHolder; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +/** + * 自动创建指令 + */ +@Slf4j +@Component +public class AutoCreateInst { + + /** + * 根据任务状态创建指令、生成下一条指令 + * 创建指令前需要判断是否条件具备:起始位置是否有货、目标位置是否有货 + */ + public void run() throws Exception { + TaskService taskserver = SpringContextHolder.getBean(TaskService.class); + InstructionService instructionService = SpringContextHolder.getBean(InstructionService.class); + RouteLineService routeLineService = SpringContextHolder.getBean(RouteLineService.class); + DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class); + + List list = taskserver.queryAll("task_status = '0'"); + for (int i = 0; i < list.size(); i++) { + TaskDto acsTask = list.get(i); + String taskid = acsTask.getTask_id(); + String taskcode = acsTask.getTask_code(); + String vehiclecode = acsTask.getVehicle_code(); + String priority = acsTask.getPriority(); + String is_send = acsTask.getIs_send(); + String start_device_code = acsTask.getStart_device_code(); + String next_device_code = acsTask.getNext_device_code(); + + String start_point_code = acsTask.getStart_point_code(); + String put_point_code = acsTask.getPut_point_code(); + String put_device_code = acsTask.getPut_device_code(); + String route_plan_code = acsTask.getRoute_plan_code(); + String vehicleType = acsTask.getVehicle_type(); + + String next_point_code = acsTask.getNext_point_code(); + + if(StrUtil.equals(is_send,"0")){ + continue; + } + + //校验路由关系 + List shortPathsList = routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code); + if (ObjectUtils.isEmpty(shortPathsList)) { + acsTask.setRemark("路由不通无法生成指令"); + taskserver.updateByCodeFromCache(acsTask); + continue; + } + + if (!StrUtil.equals(shortPathsList.get(0).getType(), "1")) { + continue; + } + + RouteLineDto routeLineDto = shortPathsList.get(0); + String path = routeLineDto.getPath(); + String type = routeLineDto.getType(); + String[] str = path.split("->"); + List pathlist = Arrays.asList(str); + int index = 0; + for (int m = 0; m < pathlist.size(); m++) { + if (pathlist.get(m).equals(start_device_code)) { + index = m + 1; + break; + } + } + next_device_code = pathlist.get(index); + + if (StrUtil.equals(appService.findDeviceTypeByCode(next_device_code), "storage")) { + next_point_code = next_device_code + "-" + acsTask.getTo_y() + "-" + acsTask.getTo_z(); + } else { + next_point_code = next_device_code; + } + + Instruction instdto = new Instruction(); + instdto.setInstruction_type(acsTask.getTask_type()); + instdto.setInstruction_id(IdUtil.simpleUUID()); + instdto.setRoute_plan_code(route_plan_code); + instdto.setRemark(acsTask.getRemark()); + instdto.setMaterial(acsTask.getMaterial()); + instdto.setQuantity(acsTask.getQuantity()); + instdto.setTask_id(taskid); + instdto.setTask_code(taskcode); + instdto.setVehicle_code(vehiclecode); + String now = DateUtil.now(); + instdto.setCreate_time(now); + instdto.setCreate_by("auto"); + instdto.setStart_device_code(start_device_code); + instdto.setStart_point_code(start_point_code); + instdto.setPut_device_code(put_device_code); + instdto.setPut_point_code(put_point_code); + instdto.setNext_device_code(next_device_code); + instdto.setNext_point_code(next_point_code); + instdto.setPriority(priority); + instdto.setInstruction_status("0"); + instdto.setExecute_device_code(start_point_code); + instdto.setVehicle_type(vehicleType); + try { + instructionService.create(instdto); + } catch (Exception e) { + acsTask.setRemark(e.getMessage()); + taskserver.updateByCodeFromCache(acsTask); + continue; + } + //创建指令后修改任务状态 + acsTask.setTask_status("1"); + taskserver.update(acsTask); + + } + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/DeviceStatusMonitor.java b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/DeviceStatusMonitor.java new file mode 100644 index 0000000..250fc06 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/DeviceStatusMonitor.java @@ -0,0 +1,40 @@ +package org.nl.modules.quartz.task; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.mnt.websocket.MsgType; +import org.nl.modules.mnt.websocket.SocketMsg; +import org.nl.modules.mnt.websocket.WebSocketServer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +/** + * 设备状态监控 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class DeviceStatusMonitor { +// @Autowired +// StageActorService stageActorService; +// private String stage_code = "SHDP"; +// +// public void run(String stageCode) throws Exception { +// try { +// if (StrUtil.isNotEmpty(stageCode)) { +// stage_code = stageCode; +// } +// JSONObject json = stageActorService.queryStageActorByStageCode(stage_code); +// SocketMsg deviceInfo = new SocketMsg(json, MsgType.INFO); +// +// WebSocketServer.sendInfo(deviceInfo, "device_monitor"); +// WebSocketServer.sendInfo(deviceInfo, "xj_device_monitor"); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/QueryZDAgvTaskStatus.java b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/QueryZDAgvTaskStatus.java new file mode 100644 index 0000000..b226b1a --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/QueryZDAgvTaskStatus.java @@ -0,0 +1,164 @@ +package org.nl.modules.quartz.task; + +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpResponse; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.agv.server.AgvService; +import org.nl.acs.agv.server.ZheDaAgvService; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 查询AGV任务状态 + */ +@Slf4j +@Component +public class QueryZDAgvTaskStatus { + + @Autowired + InstructionService instructionService; + + @Autowired + ZheDaAgvService agvService; + + + public void run() throws Exception { + HttpResponse response = agvService.queryAgvInstStatus("1"); + //查询AGV指令列表 + JSONArray inst_rows = JSONArray.parseArray(response.body()); + for (int i = 0; i < inst_rows.size(); i++) { + JSONObject inst_jo = inst_rows.getJSONObject(i); + String inst_code = inst_jo.getString("task_code"); + Instruction inst = instructionService.findByCodeFromCache(inst_code); + if (ObjectUtil.isEmpty(inst)){ + continue; + } + //反馈结果状态 + log.info("instcode:" + inst_code + "," + inst_jo.toString()); + + String state = inst_jo.getString("state"); + String vehicle = ""; + //正在执行指令agv车号 + if (!StrUtil.isEmpty(inst_jo.getString("vehicle"))) { + vehicle = inst_jo.getString("vehicle"); + inst.setCarno(vehicle); + } +// RAW:初始状态 +// ACTIVE:业务订单已激活 +// DISPATCHABLE:业务订单已通过系统验证,等待被调度执行 +// BEING_PROCESSED:业务订单正在被执行 +// WITHDRAWN:业务订单已被撤销 +// FINISHED:业务订单已完成 +// FAILED:业务订单已失败 +// UNROUTABLE:无法规划该业务订单的执行路线 + + //执行中 + if ("BEING_PROCESSED".equals(state)) { + if (inst != null) { + inst.setInstruction_status("1"); + instructionService.update(inst); + } + } else if ("FINISHED".equals(state)) { + if (inst != null) { + inst.setInstruction_status("2"); + instructionService.finish(inst); + } + } else if ("WITHDRAWN".equals(state) || "FAILED".equals(state)) { + if (inst != null) { + inst.setInstruction_status("3"); + instructionService.update(inst); + instructionService.removeByCodeFromCache(inst_jo.getString("task_code")); + } + } + JSONArray ja = inst_jo.getJSONArray("destinations"); + for (int j = 0; j < ja.size(); j++) { + JSONObject jo = ja.getJSONObject(j); + JSONArray pro_rows = jo.getJSONArray("properties"); + //Load 取货动作 Unload放货动作 Wait等待 + String operation = jo.getString("operation"); + String device = jo.getString("locationName"); + for (int k = 0; k < pro_rows.size(); k++) { + JSONObject item = pro_rows.getJSONObject(k); + if ("True".equals(item.get("value"))) { + String param = item.get("key").toString(); + //EntryRequired是否进入前等待 PauseOnStation是否离开等待 Wait在该点进行等待 + agvService.process(inst_code, param, device, operation, vehicle); + } + } + } + } + + HttpResponse response2 = agvService.queryAgvInstStatus("2"); + //查询AGV指令列表 + JSONArray inst_rows2 = JSONArray.parseArray(response.body()); + for (int i = 0; i < inst_rows2.size(); i++) { + JSONObject inst_jo = inst_rows2.getJSONObject(i); + String inst_code = inst_jo.getString("task_code"); + Instruction inst = instructionService.findByCodeFromCache(inst_code); + if (ObjectUtil.isEmpty(inst)){ + continue; + } + //反馈结果状态 + log.info("instcode:" + inst_code + "," + inst_jo.toString()); + + String state = inst_jo.getString("state"); + String vehicle = ""; + //正在执行指令agv车号 + if (!StrUtil.isEmpty(inst_jo.getString("vehicle"))) { + vehicle = inst_jo.getString("vehicle"); + inst.setCarno(vehicle); + } +// RAW:初始状态 +// ACTIVE:业务订单已激活 +// DISPATCHABLE:业务订单已通过系统验证,等待被调度执行 +// BEING_PROCESSED:业务订单正在被执行 +// WITHDRAWN:业务订单已被撤销 +// FINISHED:业务订单已完成 +// FAILED:业务订单已失败 +// UNROUTABLE:无法规划该业务订单的执行路线 + + //执行中 + if ("BEING_PROCESSED".equals(state)) { + if (inst != null) { + inst.setInstruction_status("1"); + instructionService.update(inst); + } + } else if ("FINISHED".equals(state)) { + if (inst != null) { + inst.setInstruction_status("2"); + instructionService.finish(inst); + } + } else if ("WITHDRAWN".equals(state) || "FAILED".equals(state)) { + if (inst != null) { + inst.setInstruction_status("3"); + instructionService.update(inst); + instructionService.removeByCodeFromCache(inst_jo.getString("task_code")); + } + } + JSONArray ja = inst_jo.getJSONArray("destinations"); + for (int j = 0; j < ja.size(); j++) { + JSONObject jo = ja.getJSONObject(j); + JSONArray pro_rows = jo.getJSONArray("properties"); + //Load 取货动作 Unload放货动作 Wait等待 + String operation = jo.getString("operation"); + String device = jo.getString("locationName"); + for (int k = 0; k < pro_rows.size(); k++) { + JSONObject item = pro_rows.getJSONObject(k); + if ("True".equals(item.get("value"))) { + String param = item.get("key").toString(); + //EntryRequired是否进入前等待 PauseOnStation是否离开等待 Wait在该点进行等待 + agvService.process(inst_code, param, device, operation, vehicle); + } + } + } + } + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/TestTask.java b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/TestTask.java deleted file mode 100644 index 0d67ce0..0000000 --- a/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/TestTask.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2019-2020 Zheng Jie - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.nl.modules.quartz.task; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -/** - * 测试用 - * @author Zheng Jie - * @date 2019-01-08 - */ -@Slf4j -@Component -public class TestTask { - - public void run(){ - log.info("run 执行成功"); - } - - public void run1(String str){ - log.info("run1 执行成功,参数为: {}" + str); - } - - public void run2(){ - log.info("run2 执行成功"); - } -} diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/ToAgvDevice.java b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/ToAgvDevice.java new file mode 100644 index 0000000..76f136c --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/ToAgvDevice.java @@ -0,0 +1,76 @@ +package org.nl.modules.quartz.task; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.agv.server.AgvService; +import org.nl.acs.agv.server.dto.AgvDto; +import org.nl.acs.ext.wms.service.AcsToWmsService; +import org.nl.modules.mnt.websocket.MsgType; +import org.nl.modules.mnt.websocket.SocketMsg; +import org.nl.modules.mnt.websocket.WebSocketServer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * 查询AGV设备状态 + */ +@Slf4j +@Component +public class ToAgvDevice { + + @Autowired + AcsToWmsService acsToWmsService; + @Autowired + AgvService agvService; + + public void run() throws Exception { + JSONObject json = new JSONObject(); + Map agv_map = agvService.findAllAgvFromCache(); + + JSONArray agv_rows = new JSONArray(); + JSONObject row = new JSONObject(); + + for (AgvDto agvDto : agv_map.values()) { + row.put("device_code", agvDto.getName()); + row.put("energyLevel", agvDto.getEnergyLevel()); + if (agvDto.getState().equals("UNKNOWN")) { + row.put("status_name", "有任务"); + row.put("flag", "1"); + } + if (agvDto.getState().equals("UNAVAILABLE")) { + row.put("status_name", "网络异常"); + row.put("flag", "1"); + } + if (agvDto.getState().equals("ERROR")) { + row.put("status_name", "机器错误"); + row.put("flag", "1"); + } + if (agvDto.getState().equals("IDLE")) { + row.put("status_name", "空闲"); + row.put("flag", "0"); + } + if (agvDto.getState().equals("EXECUTING")) { + row.put("status_name", "运行中"); + row.put("flag", "0"); + } + if (agvDto.getState().equals("CHARGING")) { + row.put("status_name", "充电中"); + row.put("flag", "0"); + } + row.put("transportOrder", agvDto.getTransportOrder()); + row.put("positionX", agvDto.getPositionX()); + row.put("positionY", agvDto.getPositionY()); + row.put("positionAngle", agvDto.getPositionAngle()); + agv_rows.add(row); + } + json.put("agv_rows", agv_rows); + SocketMsg deviceInfo = new SocketMsg(json, MsgType.INFO); + WebSocketServer.sendInfo(deviceInfo, "toAgvDevice_data"); + + // acsToWmsService.feedbackAgv(row); + } + +} diff --git a/acs/nladmin-ui/src/views/acs/device/config.vue b/acs/nladmin-ui/src/views/acs/device/config.vue index 263ebcb..c850948 100644 --- a/acs/nladmin-ui/src/views/acs/device/config.vue +++ b/acs/nladmin-ui/src/views/acs/device/config.vue @@ -129,6 +129,7 @@ export default { this.device_code = this.$route.params.device_code this.$nextTick(() => { get(this.device_code).then(data => { + debugger this.form = data.device // 默认是普通站点 // this.currentComponent = 'standard_ordinary_site' @@ -146,7 +147,6 @@ export default { }, methods: { changeDriver(val) { - debugger this.currentComponent = val } }