diff --git a/acs2/nladmin-system/nlsso-server/pom.xml b/acs2/nladmin-system/nlsso-server/pom.xml index ecfd722..a1c2844 100644 --- a/acs2/nladmin-system/nlsso-server/pom.xml +++ b/acs2/nladmin-system/nlsso-server/pom.xml @@ -44,7 +44,12 @@ pom - + + net.sf.json-lib + json-lib + 2.4 + jdk15 + org.dromara.dynamictp dynamic-tp-spring-boot-starter-adapter-webserver diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/rest/AgvController.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/rest/AgvController.java new file mode 100644 index 0000000..84bd61e --- /dev/null +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/rest/AgvController.java @@ -0,0 +1,51 @@ +package org.nl.acs.agv.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.nl.acs.agv.server.AgvService; +import org.nl.acs.device.device.service.DeviceService; +import org.nl.common.logging.annotation.Log; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.Enumeration; + +@RestController +@RequiredArgsConstructor +@Api(tags = "AGV任务") +@RequestMapping("/api") +@Slf4j +public class AgvController { + private final AgvService agvService; + private final DeviceService deviceService; + + + @GetMapping("/agvInst/{instcode}") + @Log("下发agv任务") + @ApiOperation("下发agv任务") + //@PreAuthorize("@el.check('routePlan:list')") + public ResponseEntity sendAgvInst(@PathVariable String instcode) throws Exception { + return new ResponseEntity<>(agvService.sendAgvInstToRmds(instcode), HttpStatus.OK); + } + + + @GetMapping("/deleteAgvInst/{instcode}") + @Log("删除agv任务") + @ApiOperation("删除agv任务") + //@PreAuthorize("@el.check('routePlan:list')") + public ResponseEntity deleteAgvInst(@PathVariable String instcode) throws Exception { + return new ResponseEntity<>(agvService.deleteRmdsAgvInst(instcode), HttpStatus.OK); + } + + + + + + + +} diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/AgvService.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/AgvService.java new file mode 100644 index 0000000..4289396 --- /dev/null +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/AgvService.java @@ -0,0 +1,59 @@ +package org.nl.acs.agv.server; + +import cn.hutool.http.HttpResponse; +import com.alibaba.fastjson.JSONObject; +import org.nl.acs.agv.server.dto.AgvDto; +import org.nl.acs.task.instruction.domain.Instruction; + +import java.util.List; +import java.util.Map; + +public interface AgvService { + + /** + * 下发agv任务 + * + * @param inst 指令对象 + */ + public HttpResponse sendAgvInstToRmds(Instruction inst) throws Exception; + + + public HttpResponse sendAgvInstToRmds(String code) throws Exception; + + + public HttpResponse queryRmdsAgvTaskStatus(); + + public HttpResponse queryRmdsAgvDeviceStatus(); + + + + + + Map findAllAgvFromCache(); + + void updateAgvFromCache(AgvDto dto); + + /** + * 删除RMDS任务 + * + * @param instCode + * @return + */ + public HttpResponse deleteRmdsAgvInst(String instCode); + + + + /** + * 查询RMDS AGV任务状态调用 + * + * @param jobno + * @param type + * @param action + * @param processingVehicle + * @return + */ + public String processRmdsInteraction(String jobno, String type, String address, String action, String processingVehicle); + + + +} diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/dto/AgvDto.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/dto/AgvDto.java new file mode 100644 index 0000000..eb2eec1 --- /dev/null +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/dto/AgvDto.java @@ -0,0 +1,162 @@ +package org.nl.acs.agv.server.dto; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class AgvDto implements Serializable { + + /** + * 名称 + */ + private String name; + + /** + * 机器人当前的自身状态 + *

+ * UNKNOWN:未知状态 + * UNAVAILABLE:通信超时或者已断开连接 + * ERROR:错误状态 + * IDLE:空闲状态 + * EXECUTING:正在执行运单 + * CHARGING:正在充电 + */ + private String state; + + /** + * 机器人的剩余电量值(单位:整数百分比) + */ + private String energyLevel; + + /** + * + */ + private String energyLevelGood; + + /** + * 机器人在 SRD 系统中的在线状态 + *

+ * TO_BE_IGNORED:机器人处于离线状态,SRD 不会标识出机器人位置。 + * TO_BE_NOTICED:机器人处于离线状态,SRD 标识出机器人的位置。 + * TO_BE_RESPECTED:机器人处于在线状态,但不能接受新的运单。 + * TO_BE_UTILIZED:机器人处于在线状态,可以接受并执行新的运单。 + */ + private String integrationLevel; + + /** + * 机器人当前的运单执行状态 + *

+ * UNAVAILABLE:无法执行任何运单和任务 + * IDLE:空闲状态 + * AWAITING_ORDER:机器人在等待运单中新的子任务 + * PROCESSING_ORDER:机器人正在执行运单 + */ + private String procState; + + /** + * 角度 + */ + private String positionAngle; + + /** + * X坐标 + */ + private String positionX; + + /** + * Y坐标 + */ + private String positionY; + + /** + * 当前任务号 + */ + private String transportOrder; + + /** + * 电池温度 + */ + private String battery_temp; + + /** + * 是否阻挡 + */ + private String blocked; + + /** + * 是否刹车 + */ + private String brake; + + /** + * 是否充电 + */ + private String charging; + + /** + * 控制器温度 + */ + private String controller_temp; + + /** + * 当前地图 + */ + private String current_map; + + /** + * 当前位置 + */ + private String current_station; + + /** + * 急停 + */ + private String emergency; + + /** + * 里程 + */ + private String odo; + + /** + * 请求电流 + */ + private String requestCurrent; + + /** + * 请求电压 + */ + private String requestVoltage; + + /** + * 软急停 + */ + private String soft_emc; + + /** + * 今天运行的里程 + */ + private String today_odo; + + /** + * 电压 + */ + private String voltage; + + /** + * x方向的速度 + */ + private String vx; + + /** + * y方向的速度 + */ + private String vy; + + /** + * 加速度 + */ + private String w; + +} diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/impl/AgvServiceImpl.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/impl/AgvServiceImpl.java new file mode 100644 index 0000000..ac10898 --- /dev/null +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/impl/AgvServiceImpl.java @@ -0,0 +1,397 @@ +package org.nl.acs.agv.server.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import org.nl.acs.agv.server.AgvService; +import org.nl.acs.agv.server.dto.AgvDto; +import org.nl.acs.device.device.service.DeviceAppService; +import org.nl.acs.device.device.service.DeviceService; +import org.nl.acs.device.device.service.impl.DeviceAppServiceImpl; +import org.nl.acs.task.instruction.domain.Instruction; +import org.nl.acs.task.instruction.service.InstructionService; +import org.nl.acs.task.task.service.TaskService; +import org.nl.config.AcsConfig; +import org.nl.config.SpringContextHolder; +import org.nl.system.service.param.ISysParamService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +@Slf4j +@Service +@RequiredArgsConstructor +public class AgvServiceImpl implements AgvService { + + + + @Autowired + DeviceAppService deviceAppService; + @Autowired + TaskService taskService; + @Autowired + InstructionService instructionService; + @Autowired + ISysParamService isysParamService; + + @Autowired + DeviceService deviceService; + + + + Map AGVDeviceStatus = new HashMap(); + + + /** + * 返回一个点位操作子任务 + * + * @param locationName 点位 + * @param operation 点位操作 + * @param propertiesType 子任务类型 + * @param pro 子任务参数 + * 调用demo:destination("sh15p", "Spin", "2", "3.14") + * demo:destination("cz14", "JackUnload", "3", "") + * @return + */ + public static JSONObject destination(String locationName, String operation, String propertiesType, String pro) { + //新增业务订单 + JSONObject destinationOrder = new JSONObject(); + //目标工作站 + destinationOrder.put("locationName", locationName); + //机器人在工作站要执行的操作 + destinationOrder.put("operation", operation); + if (propertiesType.equals("1")) {//取货前等待、取货后等待 + + //pro 1 进入离开等待 + if ("1".equals(pro)) { + JSONArray properties = new JSONArray(); + JSONObject pro1 = new JSONObject(); + pro1.put("key", "EntryRequired"); + pro1.put("value", "true"); + properties.add(pro1); + JSONObject pro2 = new JSONObject(); + pro2.put("key", "PauseOnStation"); + pro2.put("value", "true"); + properties.add(pro2); + destinationOrder.put("properties", properties); + //进入等待 离开不等待 + } else if ("2".equals(pro)) { + JSONArray properties = new JSONArray(); + JSONObject pro1 = new JSONObject(); + pro1.put("key", "EntryRequired"); + pro1.put("value", "true"); + properties.add(pro1); + JSONObject pro2 = new JSONObject(); + pro2.put("key", "PauseOnStation"); + pro2.put("value", "false"); + properties.add(pro2); + destinationOrder.put("properties", properties); + //进入不等待 离开等待 + } else if ("3".equals(pro)) { + JSONArray properties = new JSONArray(); + JSONObject pro1 = new JSONObject(); + pro1.put("key", "EntryRequired"); + pro1.put("value", "false"); + properties.add(pro1); + JSONObject pro2 = new JSONObject(); + pro2.put("key", "PauseOnStation"); + pro2.put("value", "true"); + properties.add(pro2); + destinationOrder.put("properties", properties); + //不等待 + } else { + JSONArray properties = new JSONArray(); + JSONObject pro1 = new JSONObject(); + pro1.put("key", "EntryRequired"); + pro1.put("value", "false"); + properties.add(pro1); + JSONObject pro2 = new JSONObject(); + pro2.put("key", "PauseOnStation"); + pro2.put("value", "false"); + properties.add(pro2); + destinationOrder.put("properties", properties); + } + + } else if (propertiesType.equals("2")) {//Spin转动 + JSONArray properties = new JSONArray(); + JSONObject pro1 = new JSONObject(); + pro1.put("key", "global_spin_angle");//坐标系类型,global_spin_angle为全局坐标系 + pro1.put("value", pro);//弧度值,如3.14 + properties.add(pro1); + JSONObject pro2 = new JSONObject(); + pro2.put("key", "spin_direction");//固定值 + pro2.put("value", "0");//弧度值,如0 + properties.add(pro2); + destinationOrder.put("properties", properties); + } else if (propertiesType.equals("3")) {//JackUnload,Jackload不操作 + JSONArray properties = new JSONArray(); + JSONObject pro1 = new JSONObject(); + pro1.put("key", "recognize");//固定值 + pro1.put("value", "false");//固定值 + properties.add(pro1); + destinationOrder.put("properties", properties); + } else if (propertiesType.equals("4")) { + JSONArray properties = new JSONArray(); + JSONObject pro1 = new JSONObject(); + pro1.put("key", "robot_spin_angle");//坐标系类型,robot_spin_angle为机器人坐标系 + pro1.put("value", pro);//弧度值,如3.14 + properties.add(pro1); + JSONObject pro2 = new JSONObject(); + pro2.put("key", "spin_direction");//固定值 + pro2.put("value", "0");//弧度值,如0 + properties.add(pro2); + destinationOrder.put("properties", properties); + } + return destinationOrder; + } + + + + @Override + public HttpResponse sendAgvInstToRmds(Instruction inst) throws Exception { + JSONArray ja = new JSONArray(); + JSONObject orderjo = new JSONObject(); + String instno = inst.getInstruction_code(); + orderjo.put("complete", "true"); + ja.add(destination(inst.getStart_point_code(), "Load", "1", "1")); + ja.add(destination(inst.getNext_point_code(), "Unload", "1", "1")); + orderjo.put("destinations", ja); + + JSONObject priority = new JSONObject(); + priority.put("key", "priority"); + priority.put("value", inst.getPriority()); + JSONArray properties = new JSONArray(); + properties.add(priority); + orderjo.put("properties", properties); + + if (StrUtil.equals(isysParamService.findConfigFromCache().get(AcsConfig.FORKAGV).toString(), "1")) { + String agvurl = isysParamService.findConfigFromCache().get(AcsConfig.AGVURL); + String agvport = isysParamService.findConfigFromCache().get(AcsConfig.AGVPORT); + + agvurl = agvurl + ":" + agvport + "/v1/transportOrders/" + instno; + + log.info("下发RMDS指令参数:{}", orderjo.toString()); + + HttpResponse result = null; + try { + result = HttpRequest.post(agvurl) + .header("Content-Type", "application/json") + .body(String.valueOf(orderjo))//表单内容 + .timeout(20000)//超时,毫秒 + .execute(); + } catch (Exception e) { + throw new RuntimeException("下发RMDS指令失败!", e); + } + validateRmdsControlResponse(result, "下发RMDS指令"); + return result; + } else { + return null; + } + + + } + + private void validateRmdsControlResponse(HttpResponse response, String operation) { + if (response == null || response.getStatus() != 200 || StrUtil.isEmpty(response.body())) { + throw new RuntimeException(operation + "失败:RMDS通信异常"); + } + JSONObject responseBody = JSONObject.fromObject(response.body()); + if (!"200".equals(responseBody.optString("status"))) { + throw new RuntimeException(operation + "失败,RMDS状态码:" + responseBody.optString("status")); + } + } + + + @Override + public HttpResponse sendAgvInstToRmds(String instcode) throws Exception { + InstructionService instructionService = SpringContextHolder.getBean(InstructionService.class); + Instruction inst = instructionService.findByCodeFromCache(instcode); + HttpResponse result = this.sendAgvInstToRmds(inst); + return result; + } + + + + + @Override + public HttpResponse queryRmdsAgvTaskStatus() { + + if (StrUtil.equals(isysParamService.findConfigFromCache().get(AcsConfig.FORKAGV).toString(), "1")) { + String agvurl = isysParamService.findConfigFromCache().get(AcsConfig.AGVURL); + String agvport = isysParamService.findConfigFromCache().get(AcsConfig.AGVPORT); + + agvurl = agvurl + ":" + agvport + "/v1/transportOrders/query"; + + HttpResponse result = HttpRequest.post(agvurl) + .header("Content-Type", "application/json") + .body("{}") + .timeout(20000)//超时,毫秒 + .execute(); + log.info("查询RMDS指令数据:{}", result.body()); + + return result; + } else { + + return null; + } + } + + + + + @Override + public HttpResponse queryRmdsAgvDeviceStatus() { + if (StrUtil.equals(isysParamService.findConfigFromCache().get(AcsConfig.FORKAGV).toString(), "1")) { + String agvurl = isysParamService.findConfigFromCache().get(AcsConfig.AGVURL); + String agvport = isysParamService.findConfigFromCache().get(AcsConfig.AGVPORT); + + agvurl = agvurl + ":" + agvport + "/v1/vehicles"; + + HttpResponse result = HttpRequest.post(agvurl) + .header("Content-Type", "application/json") + .body("{}") + .timeout(20000)//超时,毫秒 + .execute(); + log.info("查询RMDS车辆状态数据:{}", result.body()); + if (result.getStatus() == 200) { + JSONArray ja = JSONArray.fromObject(result.body()); + for (int i = 0; i < ja.size(); i++) { + JSONObject jo = (JSONObject) ja.get(i); + String name = jo.optString("vehicle"); + String state = jo.optString("status"); + String energyLevel = jo.optString("energyLevel"); + String transportOrder = jo.optString("task_code"); + String positionAngle = jo.optString("angle"); + String positionX = jo.optString("positionX"); + String positionY = jo.optString("positionY"); + AgvDto dto = new AgvDto(); + dto.setName(name); + dto.setEnergyLevel(energyLevel); + dto.setState(state); + dto.setPositionAngle(positionAngle); + dto.setPositionX(positionX); + dto.setPositionY(positionY); + dto.setTransportOrder(transportOrder); + + if (AGVDeviceStatus.containsKey(name)) { + AGVDeviceStatus.remove(name); + AGVDeviceStatus.put(name, dto); + } else { + AGVDeviceStatus.put(name, dto); + } + } + } + return result; + } else { + return null; + } + } + + + + + + @Override + public Map findAllAgvFromCache() { + return AGVDeviceStatus; + } + + @Override + public void updateAgvFromCache(AgvDto dto) { + if (AGVDeviceStatus.containsKey(dto.getName())) { + AGVDeviceStatus.remove(dto.getName()); + } + AGVDeviceStatus.put(dto.getName(), dto); + } + + @Override + public HttpResponse deleteRmdsAgvInst(String instCode) { + + if (StrUtil.equals(isysParamService.findConfigFromCache().get(AcsConfig.FORKAGV).toString(), "1")) { + String agvurl = isysParamService.findConfigFromCache().get(AcsConfig.AGVURL); + String agvport = isysParamService.findConfigFromCache().get(AcsConfig.AGVPORT); + + agvurl = agvurl + ":" + agvport + "/v1/transportOrders/" + instCode + "/withdrawal"; + log.info("删除RMDS指令请求agvurl:{}", agvurl); + + HttpResponse result = null; + try { + result = HttpRequest.post(agvurl) + .header("Content-Type", "application/json") + .body("{}") + .timeout(20000)//超时,毫秒 + .execute(); + } catch (Exception e) { + throw new RuntimeException("删除RMDS指令失败!", e); + } + validateRmdsControlResponse(result, "删除RMDS指令"); + log.info("删除RMDS指令请求反馈:{}", result); + + return result; + + } else { + + return null; + } + + } + + + + + //1请求取货 2取货完成 3请求放货 4放货完成 5取货完成离开 6放货完成离开 7请求进入区域 8请求离开区域 + @Override + public synchronized String processRmdsInteraction(String jobno, String type, String address, String action, String processingVehicle) { + log.info("查询到RMDS请求参数,jobno:{},address:{}", jobno + ",address:" + address + ",type:" + type + ",action:" + action); + boolean is_feedback = false; + if (address.indexOf(".") > 0) { + address = address.substring(0, address.indexOf(".")); + } else if (address.indexOf("-") > 0) { + address = address.substring(0, address.indexOf("-")); + } + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + Instruction inst = instructionService.findByCodeFromCache(jobno); + + //请求进入 + if ("onEntry".equals(type)) { + //取放货完成 + } else if ("onStation".equals(type)) { + } + + JSONObject requestjo = new JSONObject(); + if (is_feedback) { + requestjo.put("operation", action); + requestjo.put("entryRequired", "onEntry".equals(type) ? "true" : "false"); + requestjo.put("pauseOnStation", "onStation".equals(type) ? "true" : "false"); + log.info("反馈RMDS请求数据:{}", requestjo); + + String agvurl = isysParamService.findConfigFromCache().get(AcsConfig.AGVURL); + String agvport = isysParamService.findConfigFromCache().get(AcsConfig.AGVPORT); + + agvurl = agvurl + ":" + agvport + "/v1/transportOrders/" + jobno + "/interact"; + + HttpResponse result = HttpRequest.post(agvurl) + .header("Content-Type", "application/json") + .body(String.valueOf(requestjo)) + .timeout(20000)//超时,毫秒 + .execute(); + validateRmdsControlResponse(result, "RMDS站点放行"); + } + is_feedback = false; + + return requestjo.toString(); + + } + + + +} diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/config/AcsConfig.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/config/AcsConfig.java new file mode 100644 index 0000000..144fa86 --- /dev/null +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/config/AcsConfig.java @@ -0,0 +1,45 @@ +package org.nl.config; + + +public interface AcsConfig { + //指令下发agv + String FORKAGV = "forkagv"; + //同一站点运行最大任务数 + String ONEPOINTMAXTASK = "onePointMaxTask"; + //同一任务创建最大指令数 + String MAXINSTNUMBER = "maxInstNumber"; + //创建任务检查 + String CREATETASKCHECK = "createTaskCheck"; + //撤销任务检查 + String CANCELTASKCHECK = "cancelTaskCheck"; + //agv系统接口地址 + String AGVURL = "agvurl"; + //AGV系统端口 + String AGVPORT = "agvport"; + //指定AGV系统 + String AGVTYPE = "agvType"; + //WMS系统接口地址 + String WMSURL = "wmsurl"; + //WCS系统接口地址 + String WCSURL = "wcsurl"; + + String HASOTHERSYSTEM = "hasOtherSystem"; + + String ERPURL = "erpurl"; + //是否存在wms系统 + String HASWMS = "hasWms"; + //路由选择 + String ROUTE = "route"; + //忽略取放货校验 + String IGNOREHASGOODS = "ignoreHasGoods"; + //项目类型 + String BUSINESSTYPE = "businessType"; + //海亮贴标设备ip + String LETTERINGURL = "letteringUrl"; + //海亮贴标设备 + String LETTERINGPORT = "letteringPort"; + //NDC断线重连reconnection + String NDC_RECONNECTION = "NDC_reconnection"; + //自动清理日志保留时间 + String AutoCleanDays = "AutoCleanDays"; +} diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/param/ISysParamService.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/param/ISysParamService.java index cb16e34..bcde7d5 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/param/ISysParamService.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/param/ISysParamService.java @@ -37,6 +37,10 @@ public interface ISysParamService extends IService { */ void create(Param param); + void load(); + + Map findConfigFromCache(); + /** * 更新 * diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/param/dto/AcsConfigDto.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/param/dto/AcsConfigDto.java new file mode 100644 index 0000000..c334aeb --- /dev/null +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/param/dto/AcsConfigDto.java @@ -0,0 +1,32 @@ +package org.nl.system.service.param.dto; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class AcsConfigDto implements Serializable { + + private String id; + + private String code; + + private String name; + + private String value; + + private String remark; + + private String is_active; + + private String is_delete; + + private String create_by; + + private String create_time; + + private String update_by; + + private String update_time; +} + diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/param/impl/SysParamServiceImpl.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/param/impl/SysParamServiceImpl.java index 6719fa9..88734fd 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/param/impl/SysParamServiceImpl.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/param/impl/SysParamServiceImpl.java @@ -10,6 +10,8 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.beanutils.BeanUtils; +import org.nl.ApplicationAutoInitial; import org.nl.acs.task.TaskConfig; import org.nl.common.exception.BadRequestException; import org.nl.common.utils.PageUtil; @@ -21,14 +23,17 @@ import org.nl.system.service.dict.dao.Dict; import org.nl.system.service.param.ISysParamService; import org.nl.system.service.param.dao.Param; import org.nl.system.service.param.dao.mapper.SysParamMapper; +import org.nl.system.service.param.dto.AcsConfigDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** *

@@ -40,12 +45,37 @@ import java.util.Map; */ @Slf4j @Service -public class SysParamServiceImpl extends ServiceImpl implements ISysParamService { +public class SysParamServiceImpl extends ServiceImpl implements ISysParamService, ApplicationAutoInitial { @Autowired private SysParamMapper paramMapper; @Autowired private ISysDictService dictService; + Map acsconfigs = new HashMap<>(); + + @Override + public void load() { + Map map = new HashMap(); + List listacsconfigs = this.queryAll(map); + Iterator item = listacsconfigs.iterator(); + while (item.hasNext()) { + AcsConfigDto dto = (AcsConfigDto) item.next(); + acsconfigs.put(dto.getCode(), dto.getValue()); + } + + } + + + @Override + public void autoInitial() throws Exception { + this.load(); + } + + + public List queryAll (Map whereJson) { + + return paramMapper.selectList(new LambdaQueryWrapper().orderByDesc(Param::getCreate_time)); + } @Override public IPage queryPage(Map whereJson, Pageable page) { @@ -108,7 +138,7 @@ public class SysParamServiceImpl extends ServiceImpl impl return param; } - public Map queryParam(){ + public Map queryParam() { HashMap map = new HashMap(); //白班充电阈值 Param electric = this.findByCode(TaskConfig.ELECTRIC); @@ -123,16 +153,16 @@ public class SysParamServiceImpl extends ServiceImpl impl Param electric_end = this.findByCode(TaskConfig.ELECTRIC_END); if (ObjectUtil.isEmpty(electric_end)) throw new BadRequestException("白班结束时间参数异常"); - map.put("electric",electric.getValue()); - map.put("electric2",electric2.getValue()); - map.put("electric_begin",electric_begin.getValue()); - map.put("electric_end",electric_end.getValue()); + map.put("electric", electric.getValue()); + map.put("electric2", electric2.getValue()); + map.put("electric_begin", electric_begin.getValue()); + map.put("electric_end", electric_end.getValue()); return map; } @Override @Transactional(rollbackFor = Exception.class) - public void setParam(Map whereJson){ + public void setParam(Map whereJson) { Integer electric = (Integer) whereJson.get("electric"); Integer electric2 = (Integer) whereJson.get("electric2"); String electric_begin = (String) whereJson.get("electric_begin"); @@ -178,16 +208,22 @@ public class SysParamServiceImpl extends ServiceImpl impl public void sendTask(JSONObject json) { String carno = json.getString("carno"); String station = json.getString("station"); - if (StrUtil.isEmpty(carno)){ + if (StrUtil.isEmpty(carno)) { throw new BadRequestException("车辆编号不能为空"); } - if (StrUtil.isEmpty(station)){ + if (StrUtil.isEmpty(station)) { throw new BadRequestException("充电站编号不能为空"); } //判断是否已下发充电任务 - Dict dict1 = dictService.getDictByName3("station",carno,null); - if(ObjectUtil.isNotEmpty(dict1)){ - log.info("当前车辆{}已分配充电桩{},退出后续判断",carno,dict1.getPara1()); + Dict dict1 = dictService.getDictByName3("station", carno, null); + if (ObjectUtil.isNotEmpty(dict1)) { + log.info("当前车辆{}已分配充电桩{},退出后续判断", carno, dict1.getPara1()); } } + @Override + @Transactional(rollbackFor = Exception.class) + public Map findConfigFromCache() { + Map demo = (Map) ObjectUtil.clone(this.acsconfigs); + return demo; + } } diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/quartz/task/QueryRmdsAgvDeviceStatus.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/quartz/task/QueryRmdsAgvDeviceStatus.java new file mode 100644 index 0000000..9492c34 --- /dev/null +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/quartz/task/QueryRmdsAgvDeviceStatus.java @@ -0,0 +1,35 @@ +package org.nl.system.service.quartz.task; + +import cn.hutool.http.HttpResponse; +import lombok.extern.slf4j.Slf4j; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.nl.acs.agv.server.AgvService; +import org.nl.acs.task.instruction.service.InstructionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 查询AGV设备状态 + */ +@Slf4j +// 保留Quartz数据库中的既有bean_name,避免部署时必须同步修改任务表。 +@Component("queryMagicAgvDeviceStatus") +public class QueryRmdsAgvDeviceStatus { + + @Autowired + InstructionService instructionService; + + @Autowired + AgvService agvService; + + + public void run() throws Exception { + HttpResponse response = agvService.queryRmdsAgvDeviceStatus(); + if (response != null && response.getStatus() == 200) { + JSONArray ja = JSONArray.fromObject(response.body()); + + } + } + +} diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/quartz/task/QueryRmdsAgvTaskStatus.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/quartz/task/QueryRmdsAgvTaskStatus.java new file mode 100644 index 0000000..9e754cb --- /dev/null +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/quartz/task/QueryRmdsAgvTaskStatus.java @@ -0,0 +1,112 @@ +package org.nl.system.service.quartz.task; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpResponse; +import lombok.extern.slf4j.Slf4j; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.nl.acs.agv.server.AgvService; +import org.nl.acs.task.instruction.domain.Instruction; +import org.nl.acs.task.instruction.service.InstructionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 查询RMDS任务状态,并处理取货前、取货完成、放货前、放货完成四类交互。 + */ +@Slf4j +// 保留Quartz数据库中的既有bean_name,避免部署时必须同步修改任务表。 +@Component("queryMagicAgvTaskStatus") +public class QueryRmdsAgvTaskStatus { + + @Autowired + InstructionService instructionService; + + @Autowired + AgvService agvService; + + public void run() { + try { + HttpResponse response = agvService.queryRmdsAgvTaskStatus(); + if (response == null || response.getStatus() != 200 || StrUtil.isEmpty(response.body())) { + log.error("查询RMDS任务状态失败"); + return; + } + + JSONArray orders = JSONArray.fromObject(response.body()); + for (int i = 0; i < orders.size(); i++) { + JSONObject order = orders.getJSONObject(i); + String instCode = order.optString("task_code"); + Instruction inst = instructionService.findByCodeFromCache(instCode); + if (inst == null || !"1".equals(inst.getSend_status())) { + continue; + } + + try { + processOrder(inst, order); + } catch (Exception e) { + log.error("处理RMDS任务状态失败,instructionCode:{}", instCode, e); + } + } + } catch (Exception e) { + log.error("查询RMDS任务状态异常", e); + } + } + + private void processOrder(Instruction inst, JSONObject order) throws Exception { + String instCode = inst.getInstruction_code(); + String status = order.optString("status"); + String processingVehicle = order.optString("vehicle"); + log.info("RMDS任务状态,instructionCode:{},data:{}", instCode, order); + + if (!StrUtil.isEmpty(processingVehicle)) { + inst.setCarno(processingVehicle); + } + + if ("FINISHED".equals(status)) { + inst.setInstruction_status("2"); + instructionService.finish(inst); + return; + } + if ("FAILED".equals(status)) { + inst.setInstruction_status("3"); + instructionService.update(inst); + instructionService.removeByCodeFromCache(instCode); + return; + } + if ("ACTIVE".equals(status) && !StrUtil.isEmpty(processingVehicle)) { + inst.setInstruction_status("1"); + instructionService.update(inst); + } + + if (!order.containsKey("destinations")) { + return; + } + JSONArray destinations = order.getJSONArray("destinations"); + for (int i = 0; i < destinations.size(); i++) { + JSONObject destination = destinations.getJSONObject(i); + processDestination(instCode, processingVehicle, destination); + } + } + + private void processDestination(String instCode, String processingVehicle, JSONObject destination) { + if (!destination.containsKey("properties")) { + return; + } + String locationName = destination.optString("locationName"); + String operation = destination.optString("operation"); + JSONArray properties = destination.getJSONArray("properties"); + for (int i = 0; i < properties.size(); i++) { + JSONObject property = properties.getJSONObject(i); + if (!Boolean.parseBoolean(property.optString("value"))) { + continue; + } + String key = property.optString("key"); + if ("EntryRequired".equals(key)) { + agvService.processRmdsInteraction(instCode, "onEntry", locationName, operation, processingVehicle); + } else if ("PauseOnStation".equals(key)) { + agvService.processRmdsInteraction(instCode, "onStation", locationName, operation, processingVehicle); + } + } + } +}