diff --git a/acs/nladmin-system/pom.xml b/acs/nladmin-system/pom.xml index 0e88bab..17c1f36 100644 --- a/acs/nladmin-system/pom.xml +++ b/acs/nladmin-system/pom.xml @@ -420,12 +420,34 @@ lucene-analyzers-smartcn ${lucene.version} + + org.bouncycastle + bcprov-jdk15on + 1.70 + org.apache.lucene lucene-queryparser ${lucene.version} + + org.springframework.boot + spring-boot-starter-integration + + + org.springframework.integration + spring-integration-stream + + + org.springframework.integration + spring-integration-mqtt + + + com.hivemq + hivemq-mqtt-client + 1.3.3 + diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/AgvWaitUtil.java b/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/AgvWaitUtil.java index 974f2e7..cfd82d5 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/AgvWaitUtil.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/AgvWaitUtil.java @@ -4,7 +4,7 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.nl.acs.device_driver.shangdianke.PhotoelectricDetectionDeviceDriver; +import org.nl.acs.device_driver.sdk.PhotoelectricDetectionDeviceDriver; import org.nl.acs.log.service.DeviceExecuteLogService; import org.nl.acs.opc.Device; import org.nl.acs.opc.DeviceAppService; diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/XianGongAgvService.java b/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/XianGongAgvService.java index 485b4ff..3042831 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/XianGongAgvService.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/XianGongAgvService.java @@ -3,6 +3,7 @@ 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.ext.UnifiedResponse; import org.nl.acs.instruction.service.dto.Instruction; import java.util.Map; @@ -13,7 +14,115 @@ import java.util.Map; * @Date: 2022-08-15 */ public interface XianGongAgvService { - Map findAllAgvFromCache(); + /** + * 下发叉车运单 + * + * @param dto + * @return + */ + public UnifiedResponse sendOrderSequencesToForklift(Instruction dto); + + /** + * 下发运单序列 + * + * @param inst + * @return + * @throws Exception + */ + public UnifiedResponse sendOrderSequencesToXZ(Instruction inst); + + /** + * 追加运单 + * + * @param inst + * @return + * @throws Exception + */ + public UnifiedResponse addOrderSequences(Instruction inst); + + /** + * @param reqParam + * @param + * @return + * @throws Exception + */ + public UnifiedResponse markComplete(JSONObject reqParam); + + /** + * 查询AGV状态 + * + * @return + */ + public UnifiedResponse queryXZAgvDeviceStatus(String vehicles, Class type); + + /** + * @param type + * @param + * @return + */ + public UnifiedResponse queryXZAgvInstStatus(Class type); + + /** + * 根据运单号查询运单状态 + * + * @param type + * @param + * @return + */ + public UnifiedResponse queryXZAgvInstStatusByCode(String instCode, Class type); + + + /** + * 删除先知任务 + * + * @param instCode + * @return + */ + public UnifiedResponse deleteXZAgvInst(String instCode); + + + /** + * 查询场景中指定机器人信息 + */ + public UnifiedResponse getRobotInfo(String robotCode, Class type); + + + /** + * 占用互斥组 + * + * @param reqParam + * @param + * @return + */ + public UnifiedResponse getBlockGroup(JSONObject reqParam); + + /** + * 查询互斥组状态 + * + * @param reqParam + * @param + * @return + */ + public UnifiedResponse blockGroupStatus(JSONObject reqParam); + + + /** + * 释放互斥组 + * + * @param reqParam + * @param + * @return + */ + public UnifiedResponse releaseBlockGroup(JSONObject reqParam); + + + /** + * 查询所有AGV + * + * @return + */ + public Map findAllAgvFromCache(); + /** * 查询自动门状态 * @@ -24,59 +133,38 @@ public interface XianGongAgvService { /** * 先工agv 等待点请求 - *AGV->ACS - * @param + * AGV->ACS + * + * @param param * @return */ public String waitPointRequest(String param); - /** - * acs->agv - * 关闭运单系列 - * @param code - * @return - */ - public HttpResponse markComplete(String code); /** - * 查询AGV状态 - * @return - */ - public HttpResponse queryXZAgvDeviceStatus(); - - public HttpResponse queryXZAgvInstStatus(); - - /** - * 删除先知任务 - * - * @param instCode - * @return - */ - public HttpResponse deleteXZAgvInst(String instCode); - - - /** - * 下发运单序列 + * 组织json数据 * * @param inst * @return * @throws Exception */ - public HttpResponse sendOrderSequencesToXZ(Instruction inst) throws Exception; + public String sendOrderSequencesParam(Instruction inst); - public HttpResponse addOrderSequences(Instruction inst) throws Exception; /** - * 组织json数据 + * 创建 * - * @param + * @param inst + * @param type * @return - * @throws Exception */ - public String sendOrderSequencesParam(Instruction inst) throws Exception; - - public JSONObject createOrederData(Instruction inst, String type); - JSONObject xgAGVWaitPointRequest(JSONObject requestParam); + /** + * 请求取货放货 + * + * @param requestParam + * @return + */ + public JSONObject xgAGVWaitPointRequest(JSONObject requestParam); } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/impl/XianGongAgvServiceImpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/impl/XianGongAgvServiceImpl.java index 383b27c..aeac37c 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/impl/XianGongAgvServiceImpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/agv/server/impl/XianGongAgvServiceImpl.java @@ -14,7 +14,9 @@ import org.nl.acs.agv.server.AgvWaitUtil; import org.nl.acs.agv.server.XianGongAgvService; import org.nl.acs.agv.server.dto.AgvDto; import org.nl.acs.config.AcsConfig; +import org.nl.acs.ext.UnifiedResponse; import org.nl.acs.ext.wms.service.AcsToWmsService; +import org.nl.acs.ext.xg.XgHttpUtil; import org.nl.acs.instruction.service.InstructionService; import org.nl.acs.instruction.service.dto.Instruction; import org.nl.acs.opc.Device; @@ -49,12 +51,103 @@ public class XianGongAgvServiceImpl implements XianGongAgvService { private AgvWaitUtil agvWaitUtil; @Autowired private TaskService taskService; + @Autowired + private XgHttpUtil xgHttpUtil; private Map AGVDeviceStatus = new HashMap<>(); @Value("${server.port}") public int port; + @Override + public UnifiedResponse sendOrderSequencesToXZ(Instruction inst) { + JSONObject reqParam = new JSONObject(); + reqParam.put("id", inst.getInstruction_code()); + reqParam.put("complete", true); + reqParam.put("blocks", createBlocksData(inst)); + reqParam.put("priority", inst.getPriority()); + String path = "/setOrder"; + return xgHttpUtil.sendPostRequest(path, reqParam); + } + + @Override + public UnifiedResponse sendOrderSequencesToForklift(Instruction inst) { + JSONObject reqParam = new JSONObject(); + reqParam.put("id", inst.getInstruction_code()); + reqParam.put("complete", true); + reqParam.put("blocks", createBlocksForklift(inst)); + reqParam.put("priority", inst.getPriority()); + String path = "/setOrder"; + return xgHttpUtil.sendPostRequest(path, reqParam); + } + + @Override + public UnifiedResponse markComplete(JSONObject reqParam) { + String path = "/markComplete"; + return xgHttpUtil.sendPostRequest(path, reqParam); + } + + + @Override + public UnifiedResponse queryXZAgvDeviceStatus(String vehicles, Class type) { + String path = "/robotsStatus" + vehicles == null ? "" : "?vehicles = " + vehicles; + return xgHttpUtil.sendGetRequest(path, type); + } + + + @Override + public UnifiedResponse queryXZAgvInstStatus(Class type) { + String path = "/orders?page=1&size=80&orderBy=createTime&orderMethod=descending"; + return xgHttpUtil.sendGetRequest(path, type); + } + + @Override + public UnifiedResponse queryXZAgvInstStatusByCode(String instCode, Class type) { + String path = "/orderDetails/" + instCode; + return xgHttpUtil.sendGetRequest(path, type); + } + + + @Override + public UnifiedResponse deleteXZAgvInst(String instCode) { + //String path = "/api/route/transportOrders/" + instCode + "/withdrawal"; + String path = "/terminate"; + JSONObject reqParam = new JSONObject(); + reqParam.put("id", instCode); + return xgHttpUtil.sendPostRequest(path, reqParam); + } + + @Override + public UnifiedResponse addOrderSequences(Instruction inst) { + JSONObject addOrder = createOrederData(inst, "1"); + String path = "/api/route/transportOrders/" + inst.getInstruction_code(); + return xgHttpUtil.sendPostRequest(path, addOrder); + } + + @Override + public UnifiedResponse getRobotInfo(String robotCode, Class type) { + String path = "/robotsStatus?vehicles=" + robotCode; + return xgHttpUtil.sendGetRequest(path, type); + } + + @Override + public UnifiedResponse getBlockGroup(JSONObject reqParam) { + String path = "/getBlockGroup"; + return xgHttpUtil.sendPostRequest(path, reqParam); + } + + @Override + public UnifiedResponse releaseBlockGroup(JSONObject reqParam) { + String path = "/releaseBlockGroup"; + return xgHttpUtil.sendPostRequest(path, reqParam); + } + + @Override + public UnifiedResponse blockGroupStatus(JSONObject reqParam) { + String path = "/blockGroupStatus"; + return xgHttpUtil.sendPostRequest(path, reqParam); + } + @Override public String waitPointRequest(String param) { log.info("收到AGV请求参数:{}", param); @@ -99,186 +192,185 @@ public class XianGongAgvServiceImpl implements XianGongAgvService { } - @Override - public HttpResponse markComplete(String code) { - String api = "/api/route/orderSequences/" + code + "/markComplete"; - if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { - String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); - String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); +// @Override +// public HttpResponse markComplete(String code) { +// String api = "/api/route/orderSequences/" + code + "/markComplete"; +// if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { +// String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); +// String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); +// +// agvurl = agvurl + ":" + agvport + "/api/route/orderSequences/" + code + "/markComplete"; +// log.info("关闭agv运单序列请求:{}", agvurl); +// +// HttpResponse result = HttpRequest.post(agvurl) +// //.body(String.valueOf(orderjo))//表单内容 +// .timeout(20000)//超时,毫秒 +// .execute(); +// log.info("关闭agv运单序列请求反馈:{}", result); +// +// return result; +// } else { +// return null; +// } +// +// } - agvurl = agvurl + ":" + agvport + "/api/route/orderSequences/" + code + "/markComplete"; - log.info("关闭agv运单序列请求:{}", agvurl); +// @Override +// public HttpResponse queryXZAgvDeviceStatus() { +// +// if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { +// String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); +// String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); +// +// String agvurl1 = agvurl + ":" + agvport + "/api/route/vehicles"; +// String agvurl2 = agvurl + ":" + agvport + "/api/route/vehicleDetails"; +// +// HttpResponse result = HttpRequest.get(agvurl1) +// .timeout(20000)//超时,毫秒 +// .execute(); +// +// +// HttpResponse result2 = HttpRequest.get(agvurl2) +// .timeout(20000)//超时,毫秒 +// .execute(); +// +// System.out.println("查询agv状态数据:" + result.body()); +// if (result.getStatus() == 200) { +// JSONArray ja = (JSONArray) JSONArray.parse(result.body()); +// +// for (int i = 0; i < ja.size(); i++) { +// JSONObject jo = (JSONObject) ja.get(i); +// String name = jo.getString("name"); +// String state = jo.getString("state"); +// String energyLevel = jo.getString("energyLevel"); +// String transportOrder = jo.getString("transportOrder"); +// JSONObject detailjo = (JSONObject) JSONObject.parse(result2.body()); +// JSONObject item = (JSONObject) detailjo.get(name); +// String x = item.getString("x"); +// String y = item.getString("y"); +// String angle = item.getString("angle"); +// AgvDto dto = new AgvDto(); +// dto.setName(name); +// dto.setEnergyLevel(energyLevel); +// dto.setState(state); +// dto.setTransportOrder(transportOrder); +// dto.setPositionAngle(angle); +// dto.setPositionX(x); +// dto.setPositionY(y); +// if (AGVDeviceStatus.containsKey(name)) { +// AGVDeviceStatus.remove(name); +// AGVDeviceStatus.put(name, dto); +// } else { +// AGVDeviceStatus.put(name, dto); +// } +// } +// } +// return result; +// } else { +// return null; +// } +// +// +// } - HttpResponse result = HttpRequest.post(agvurl) - //.body(String.valueOf(orderjo))//表单内容 - .timeout(20000)//超时,毫秒 - .execute(); - log.info("关闭agv运单序列请求反馈:{}", result); +// @Override +// public HttpResponse queryXZAgvInstStatus() { +// if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { +// String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); +// String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); +// +// agvurl = agvurl + ":" + agvport + "/orders?page=1&size=200"; +// +// HttpResponse result = HttpRequest.get(agvurl) +// .timeout(20000)//超时,毫秒 +// .execute(); +// log.info("queryXZAgvInstStatus----查询agv指令数据:{}" + result.body()); +// return result; +// } else { +// +// return null; +// } +// } - return result; - } else { - return null; - } +// @Override +// public HttpResponse deleteXZAgvInst(String instCode) { +// if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { +// String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); +// String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); +// +// JSONObject param = new JSONObject(); +// param.put("id", instCode); +// param.put("disableVehicle", false); +// agvurl = agvurl + ":" + agvport + "/terminate"; +// log.info("删除agv指令请求agvurl:{}", agvurl); +// try { +// HttpResponse result = HttpRequest.post(agvurl) +// .body(param.toJSONString()) +// .timeout(20000)//超时,毫秒 +// .execute(); +// log.info("删除agv指令请求反馈:{}", result); +// return result; +// } catch (Exception e) { +// log.error("取消AGV指令信息错误:{}", e.getMessage()); +// throw new BadRequestException(e.getMessage()); +// } +// } else { +// return null; +// } +// } +// @Override +// public HttpResponse sendOrderSequencesToXZ(Instruction inst) throws Exception { +// JSONObject jo = new JSONObject(); +// jo.put("id", inst.getInstruction_code()); +// jo.put("complete", true); +// jo.put("blocks", createBlocksData(inst)); +// jo.put("priority", inst.getPriority()); +// log.info("任务号:{},指令号{},下发agv订单序列参数:{}", inst.getTask_code(), inst.getInstruction_code(), jo.toString()); +// +// if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { +// String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); +// String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); +// agvurl = agvurl + ":" + agvport + "/setOrder"; +// +// HttpResponse result = HttpRequest.post(agvurl) +// .body(String.valueOf(jo))//表单内容 +// .timeout(20000)//超时,毫秒 +// .execute(); +// log.info(agvurl); +// log.info("任务号:{},指令号{},状态{},下发agv订单序列反馈:{}", inst.getTask_code(), inst.getInstruction_code(), result.getStatus(), result.body()); +// return result; +// } else { +// return null; +// } +// } - } +// @Override +// public HttpResponse addOrderSequences(Instruction inst) throws Exception { +// JSONObject orderjo = createOrederData(inst, "1"); +// log.info("指令号:{},追加agv订单序列参数:{}", inst.getInstruction_code(), orderjo.toString()); +// +// if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { +// String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); +// String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); +// +// agvurl = agvurl + ":" + agvport + "/api/route/transportOrders/" + inst.getInstruction_code(); +// +// HttpResponse result = HttpRequest.post(agvurl) +// .body(String.valueOf(orderjo))//表单内容 +// .timeout(20000)//超时,毫秒 +// .execute(); +// log.info(agvurl); +// log.info("任务号:{},指令号{},状态{},追加agv订单序列参数:{}", inst.getTask_code(), inst.getInstruction_code(), result.getStatus(), result.body()); +// +// return result; +// } else { +// return null; +// } +// } @Override - public HttpResponse queryXZAgvDeviceStatus() { - - if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { - String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); - String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); - - String agvurl1 = agvurl + ":" + agvport + "/api/route/vehicles"; - String agvurl2 = agvurl + ":" + agvport + "/api/route/vehicleDetails"; - - HttpResponse result = HttpRequest.get(agvurl1) - .timeout(20000)//超时,毫秒 - .execute(); - - - HttpResponse result2 = HttpRequest.get(agvurl2) - .timeout(20000)//超时,毫秒 - .execute(); - - System.out.println("查询agv状态数据:" + result.body()); - if (result.getStatus() == 200) { - JSONArray ja = (JSONArray) JSONArray.parse(result.body()); - - for (int i = 0; i < ja.size(); i++) { - JSONObject jo = (JSONObject) ja.get(i); - String name = jo.getString("name"); - String state = jo.getString("state"); - String energyLevel = jo.getString("energyLevel"); - String transportOrder = jo.getString("transportOrder"); - JSONObject detailjo = (JSONObject) JSONObject.parse(result2.body()); - JSONObject item = (JSONObject) detailjo.get(name); - String x = item.getString("x"); - String y = item.getString("y"); - String angle = item.getString("angle"); - AgvDto dto = new AgvDto(); - dto.setName(name); - dto.setEnergyLevel(energyLevel); - dto.setState(state); - dto.setTransportOrder(transportOrder); - dto.setPositionAngle(angle); - dto.setPositionX(x); - dto.setPositionY(y); - if (AGVDeviceStatus.containsKey(name)) { - AGVDeviceStatus.remove(name); - AGVDeviceStatus.put(name, dto); - } else { - AGVDeviceStatus.put(name, dto); - } - } - } - return result; - } else { - return null; - } - - - } - - @Override - public HttpResponse queryXZAgvInstStatus() { - if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { - String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); - String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); - - agvurl = agvurl + ":" + agvport + "/orders?page=1&size=200"; - - HttpResponse result = HttpRequest.get(agvurl) - .timeout(20000)//超时,毫秒 - .execute(); - log.info("queryXZAgvInstStatus----查询agv指令数据:{}" + result.body()); - return result; - } else { - - return null; - } - } - - @Override - public HttpResponse deleteXZAgvInst(String instCode) { - if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { - String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); - String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); - - JSONObject param = new JSONObject(); - param.put("id", instCode); - param.put("disableVehicle", false); - agvurl = agvurl + ":" + agvport + "/terminate"; - log.info("删除agv指令请求agvurl:{}", agvurl); - try { - HttpResponse result = HttpRequest.post(agvurl) - .body(param.toJSONString()) - .timeout(20000)//超时,毫秒 - .execute(); - log.info("删除agv指令请求反馈:{}", result); - return result; - } catch (Exception e) { - log.error("取消AGV指令信息错误:{}", e.getMessage()); - throw new BadRequestException(e.getMessage()); - } - } else { - return null; - } - } - - @Override - public HttpResponse sendOrderSequencesToXZ(Instruction inst) throws Exception { - JSONObject jo = new JSONObject(); - jo.put("id", inst.getInstruction_code()); - jo.put("complete", true); - jo.put("blocks", createBlocksData(inst)); - jo.put("priority", inst.getPriority()); - log.info("任务号:{},指令号{},下发agv订单序列参数:{}", inst.getTask_code(), inst.getInstruction_code(), jo.toString()); - - if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { - String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); - String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); - agvurl = agvurl + ":" + agvport + "/setOrder"; - - HttpResponse result = HttpRequest.post(agvurl) - .body(String.valueOf(jo))//表单内容 - .timeout(20000)//超时,毫秒 - .execute(); - log.info(agvurl); - log.info("任务号:{},指令号{},状态{},下发agv订单序列反馈:{}", inst.getTask_code(), inst.getInstruction_code(), result.getStatus(), result.body()); - return result; - } else { - return null; - } - } - - @Override - public HttpResponse addOrderSequences(Instruction inst) throws Exception { - JSONObject orderjo = createOrederData(inst, "1"); - log.info("指令号:{},追加agv订单序列参数:{}", inst.getInstruction_code(), orderjo.toString()); - - if (StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { - String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); - String agvport = paramService.findByCode(AcsConfig.AGV_PORT).getValue(); - - agvurl = agvurl + ":" + agvport + "/api/route/transportOrders/" + inst.getInstruction_code(); - - HttpResponse result = HttpRequest.post(agvurl) - .body(String.valueOf(orderjo))//表单内容 - .timeout(20000)//超时,毫秒 - .execute(); - log.info(agvurl); - log.info("任务号:{},指令号{},状态{},追加agv订单序列参数:{}", inst.getTask_code(), inst.getInstruction_code(), result.getStatus(), result.body()); - - return result; - } else { - return null; - } - } - - @Override - public String sendOrderSequencesParam(Instruction inst) throws Exception { + public String sendOrderSequencesParam(Instruction inst) { JSONObject jo = new JSONObject(); jo.put("intendedVehicle", ""); jo.put("category", "Park"); @@ -725,4 +817,137 @@ public class XianGongAgvServiceImpl implements XianGongAgvService { throw new BadRequestException("请求失败,IN OUT 站点错误!"); } + + /** + * 叉车运单动作块 + * + * @param inst + * @return + */ + private JSONArray createBlocksForklift(Instruction inst) { + JSONArray ja = new JSONArray(); + //起点 + Device startDevice = deviceAppService.findDeviceByCode(inst.getStart_device_code()); + //忽略取货校验 + if ("true".equals(startDevice.getExtraValue().get("ignore_pickup_check"))) { + //取货前等待 + JSONObject jo = new JSONObject(); + //动作块id + jo.put("blockId", IdUtil.simpleUUID()); + //目的地名称 + jo.put("location", inst.getStart_point_code() + "INGET"); + //执行脚本 + jo.put("operation", "script"); + jo.put("id", inst.getStart_point_code() + "INGET"); + //通信脚本,动作前后与现场设备交互的场景 + jo.put("script_name", "userpy/interact.py"); + JSONObject script_args = new JSONObject(); + //更改为现场设备IP及PORT +// script_args.put("addr", addr); + JSONObject data = new JSONObject(); + JSONObject reach = new JSONObject(); + reach.put("task_code", inst.getInstruction_code()); + reach.put("address", inst.getStart_point_code() + "INGET"); + data.put("reach", reach); + script_args.put("data", data); + script_args.put("protocol", "HTTP"); + jo.put("script_args", script_args); + ja.add(jo); + } + //货叉加载货物,会将叉车状态变成载货中 + JSONObject jo1 = new JSONObject(); + jo1.put("blockId", IdUtil.simpleUUID()); + jo1.put("location", inst.getStart_point_code()); + jo1.put("operation", "ForkLoad"); + //行走高度 + jo1.put("start_height", "0.1"); + //取货高度 +// jo1.put("end_height", inst.getStart_height()); + //升起信号 + jo1.put("operationArgs", new JSONObject() {{ + put("recognize", true); + }}); + ja.add(jo1); + + //取货完成等待 + if ("true".equals(startDevice.getExtraValue().get("ignore_pickup_check"))) { + JSONObject jo2 = new JSONObject(); + jo2.put("blockId", IdUtil.simpleUUID()); + jo2.put("location", inst.getStart_point_code() + "OUTGET"); + jo2.put("operation", "script"); + jo2.put("id", inst.getStart_point_code() + "OUTGET"); + jo2.put("script_name", "userpy/interact.py"); + JSONObject script_args2 = new JSONObject(); +// script_args2.put("addr", addr); + JSONObject data2 = new JSONObject(); + JSONObject reach2 = new JSONObject(); + reach2.put("task_code", inst.getInstruction_code()); + reach2.put("address", inst.getStart_point_code() + "OUTGET"); + data2.put("reach", reach2); + script_args2.put("data", data2); + script_args2.put("protocol", "HTTP"); + jo2.put("script_args", script_args2); + ja.add(jo2); + } + + //起点 + Device nextDevice = deviceAppService.findDeviceByCode(inst.getNext_device_code()); + //忽略放货校验 + if ("true".equals(nextDevice.getExtraValue().get("ignore_release_check"))) { + //放货前等待 + JSONObject jo3 = new JSONObject(); + jo3.put("blockId", IdUtil.simpleUUID()); + jo3.put("location", inst.getNext_point_code() + "INPUT"); + jo3.put("operation", "script"); + jo3.put("id", inst.getNext_point_code() + "INPUT"); + jo3.put("script_name", "userpy/interact.py"); + JSONObject script_args3 = new JSONObject(); +// script_args3.put("addr", addr); + JSONObject data3 = new JSONObject(); + JSONObject reach3 = new JSONObject(); + reach3.put("task_code", inst.getInstruction_code()); + reach3.put("address", inst.getNext_point_code() + "INPUT"); + data3.put("reach", reach3); + script_args3.put("data", data3); + script_args3.put("protocol", "HTTP"); + jo3.put("script_args", script_args3); + ja.add(jo3); + } + + + //ForkUnload(货叉卸载货物,会将叉车的状态变成非载货中) + JSONObject jo2 = new JSONObject(); + jo2.put("blockId", IdUtil.simpleUUID()); + jo2.put("location", inst.getStart_point_code()); + jo2.put("operation", "ForkUnload"); + //行走高度 + jo2.put("start_height", "0.2"); + //放货高度 +// jo2.put("end_height", inst.getNext_height()); + ja.add(jo2); + + + //忽略放货校验 + if ("true".equals(nextDevice.getExtraValue().get("ignore_release_check"))) { + //放货完成等待 + com.alibaba.fastjson.JSONObject jo5 = new com.alibaba.fastjson.JSONObject(); + jo5.put("blockId", IdUtil.simpleUUID()); + jo5.put("location", inst.getNext_point_code() + "OUTPUT"); + jo5.put("operation", "script"); + jo5.put("id", inst.getNext_point_code() + "OUTPUT"); + jo5.put("script_name", "userpy/interact.py"); + com.alibaba.fastjson.JSONObject script_args5 = new com.alibaba.fastjson.JSONObject(); +// script_args5.put("addr", addr); + com.alibaba.fastjson.JSONObject data5 = new com.alibaba.fastjson.JSONObject(); + com.alibaba.fastjson.JSONObject reach5 = new com.alibaba.fastjson.JSONObject(); + reach5.put("task_code", inst.getInstruction_code()); + reach5.put("address", inst.getNext_point_code() + "OUTPUT"); + data5.put("reach", reach5); + script_args5.put("data", data5); + script_args5.put("protocol", "HTTP"); + jo5.put("script_args", script_args5); + ja.add(jo5); + } + return ja; + } } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device.xls b/acs/nladmin-system/src/main/java/org/nl/acs/device.xls index 7e2a183..182aa3b 100644 Binary files a/acs/nladmin-system/src/main/java/org/nl/acs/device.xls and b/acs/nladmin-system/src/main/java/org/nl/acs/device.xls differ diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device/device_driver/DriverTypeEnum.java b/acs/nladmin-system/src/main/java/org/nl/acs/device/device_driver/DriverTypeEnum.java index 24663ad..b827afc 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/device/device_driver/DriverTypeEnum.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device/device_driver/DriverTypeEnum.java @@ -11,7 +11,9 @@ import com.alibaba.fastjson.JSONObject; public enum DriverTypeEnum { ORDINARY_SITE(1, "standard_ordinary_site", "普通站点", "station"), STANDARD_STORAGE(2, "standard_storage", "标准版-货架", "storage"), - PHOTOELECTRIC_DETECTION_DEVICE_DRIVER(3, "photoelectric_detection_station", "光电检测站点", "station"); + PHOTOELECTRIC_DETECTION_DEVICE_DRIVER(3, "photoelectric_detection_station", "光电检测站点", "station"), + XIANGONG_AGV_DEVICE_DRIVER(4, "xg_agv", "仙工AGV", "agv"), + RGV_DEVICE_DRIVER(5, "rgv_station", "RGV", "rgv"); //驱动索引 private int index; //驱动编码 diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device/service/dto/OpcDto.java b/acs/nladmin-system/src/main/java/org/nl/acs/device/service/dto/OpcDto.java index 37f526f..8972c4b 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/device/service/dto/OpcDto.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device/service/dto/OpcDto.java @@ -27,6 +27,8 @@ public class OpcDto implements Serializable { */ private String opc_name; + private String topic; + /** * OPC地址 */ diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/DeviceDriverBaseReader.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/DeviceDriverBaseReader.java new file mode 100644 index 0000000..b1bb64d --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/DeviceDriverBaseReader.java @@ -0,0 +1,221 @@ +package org.nl.acs.device_driver; + +import com.alibaba.fastjson.JSON; +import org.nl.acs.device_driver.utils.ArrayComparisonUtil; +import org.nl.acs.device_driver.utils.ArrayConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * @Description + * @Author Gengby + * @Date 2024/4/1 + */ +public interface DeviceDriverBaseReader { + + public static final Logger LOGGER = LoggerFactory.getLogger(DeviceDriverBaseReader.class); + + public static final boolean ENABLE_LOGGING_FLAG = true; + + public static final String PRE_LAST = "last"; + + public static final Map, Map> FIELD_CACHE = new ConcurrentHashMap<>(); + + public static final Map, Supplier> DEFAULT_VALUES_SUPPLIERS = createDefaultValuesSuppliers(); + + public static final List> LIMIT_CLASS_TYPE_LIST = Arrays.asList(double.class, Double.class, Float.class, float.class); + + public static final List> ARRAY_CLASS_TYPE_LIST = Arrays.asList(int[].class, Integer[].class, byte[].class, Byte[].class, short[].class, Short[].class, long[].class, Long[].class, float[].class, Float[].class, double[].class, Double[].class, char[].class, Character[].class, boolean[].class, Boolean[].class, String[].class); + + static Map, Supplier> createDefaultValuesSuppliers() { + Map, Supplier> defaultMap = new HashMap<>(); + defaultMap.put(int.class, () -> 0); + defaultMap.put(Integer.class, () -> 0); + defaultMap.put(int[].class, () -> new int[0]); + defaultMap.put(Integer[].class, () -> new Integer[0]); + defaultMap.put(double.class, () -> 0.0d); + defaultMap.put(Double.class, () -> 0.0d); + defaultMap.put(double[].class, () -> new double[0]); + defaultMap.put(Double[].class, () -> new Double[0]); + defaultMap.put(long.class, () -> 0L); + defaultMap.put(Long.class, () -> 0L); + defaultMap.put(long[].class, () -> new long[0]); + defaultMap.put(Long[].class, () -> new Long[0]); + defaultMap.put(boolean.class, () -> false); + defaultMap.put(Boolean.class, () -> Boolean.FALSE); + defaultMap.put(boolean[].class, () -> new boolean[0]); + defaultMap.put(Boolean[].class, () -> new Boolean[0]); + defaultMap.put(byte.class, () -> (byte) 0); + defaultMap.put(Byte.class, () -> (byte) 0); + defaultMap.put(byte[].class, () -> new byte[0]); + defaultMap.put(Byte[].class, () -> new Byte[0]); + defaultMap.put(char.class, () -> '\u0000'); + defaultMap.put(Character.class, () -> '\u0000'); + defaultMap.put(char[].class, () -> new char[0]); + defaultMap.put(Character[].class, () -> new Character[0]); + defaultMap.put(short.class, () -> (short) 0); + defaultMap.put(Short.class, () -> (short) 0); + defaultMap.put(short[].class, () -> new short[0]); + defaultMap.put(Short[].class, () -> new Short[0]); + defaultMap.put(float.class, () -> 0.0f); + defaultMap.put(Float.class, () -> 0.0f); + defaultMap.put(float[].class, () -> new float[0]); + defaultMap.put(Float[].class, () -> new Float[0]); + defaultMap.put(String.class, () -> ""); + defaultMap.put(String[].class, () -> new String[0]); + return defaultMap; + } + + static Map, Supplier> getLimitPlacesValue(Class filedType, T value) { + Map, Supplier> limitMap = new HashMap<>(); + Map, Function>> strategyMap = new HashMap<>(); + strategyMap.put(Double.class, v -> () -> ArrayConverter.limitDoublePlaces(String.valueOf(value))); + strategyMap.put(double.class, v -> () -> ArrayConverter.limitDoublePlaces(String.valueOf(value))); + strategyMap.put(Float.class, v -> () -> ArrayConverter.limitFloatPlaces(String.valueOf(value))); + strategyMap.put(float.class, v -> () -> ArrayConverter.limitFloatPlaces(String.valueOf(value))); + Optional.ofNullable(strategyMap.get(filedType)).map(func -> func.apply(value)).ifPresent(supplier -> limitMap.put(filedType, supplier)); + return limitMap; + } + + static Map, Supplier> getArrayValue(Class filedType, T value) { + Map, Supplier> arrayMap = new HashMap<>(); + Map, Function>> strategyMap = new HashMap<>(); + strategyMap.put(int[].class, v -> () -> ArrayConverter.convertStringToArrayOfInt(JSON.toJSONString(v))); + strategyMap.put(Integer[].class, v -> () -> ArrayConverter.convertStringToArrayOfIntegerObject(JSON.toJSONString(v))); + strategyMap.put(short[].class, v -> () -> ArrayConverter.convertStringToArrayOfShort(JSON.toJSONString(v))); + strategyMap.put(Short[].class, v -> () -> ArrayConverter.convertStringToArrayOfShortObject(JSON.toJSONString(v))); + strategyMap.put(byte[].class, v -> () -> ArrayConverter.convertStringToArrayOfByte(JSON.toJSONString(v))); + strategyMap.put(Byte[].class, v -> () -> ArrayConverter.convertStringToArrayOfByteObject(JSON.toJSONString(v))); + strategyMap.put(long[].class, v -> () -> ArrayConverter.convertStringToArrayOfLong(JSON.toJSONString(v))); + strategyMap.put(Long[].class, v -> () -> ArrayConverter.convertStringToArrayOfLongObject(JSON.toJSONString(v))); + strategyMap.put(char[].class, v -> () -> ArrayConverter.convertStringToArrayOfChar(JSON.toJSONString(v))); + strategyMap.put(Character[].class, v -> () -> ArrayConverter.convertStringToArrayOfCharacterObject(JSON.toJSONString(v))); + strategyMap.put(boolean[].class, v -> () -> ArrayConverter.convertStringToArrayOfBoolean(JSON.toJSONString(v))); + strategyMap.put(Boolean[].class, v -> () -> ArrayConverter.convertStringToArrayOfBooleanObject(JSON.toJSONString(v))); + strategyMap.put(String[].class, v -> () -> ArrayConverter.convertStringToArrayOfString(JSON.toJSONString(v))); + strategyMap.put(Double[].class, v -> () -> ArrayConverter.convertStringToArrayOfDoubleObject(JSON.toJSONString(v), ArrayConverter::limitDoublePlaces)); + strategyMap.put(double[].class, v -> () -> ArrayConverter.convertStringToArrayOfDouble(JSON.toJSONString(v), ArrayConverter::limitDoublePlaces)); + strategyMap.put(Float[].class, v -> () -> ArrayConverter.convertStringToArrayOfFloatObject(JSON.toJSONString(v), ArrayConverter::limitFloatPlaces)); + strategyMap.put(float[].class, v -> () -> ArrayConverter.convertStringToArrayOfFloat(JSON.toJSONString(v), ArrayConverter::limitFloatPlaces)); + Optional.ofNullable(strategyMap.get(filedType)).map(func -> func.apply(value)).ifPresent(supplier -> arrayMap.put(filedType, supplier)); + return arrayMap; + } + + + static T getDefaultPrimitiveValue(Class type) { + Supplier supplier = DEFAULT_VALUES_SUPPLIERS.get(type); + return (supplier != null) ? (T) supplier.get() : null; + } + + default & KeyProvider> void loadAssignData(String currentDeviceCode, Class enumClass) { + initializeFieldCache(this.getClass()); + + Map lastValues = new HashMap<>(); + Map fields = FIELD_CACHE.get(this.getClass()); + + for (E item : enumClass.getEnumConstants()) { + Field field = fields.get(item.getKey()); + if (field != null) { + try { + Object oldValue = field.get(this); + Object tempOldValue = null; + if (oldValue != null && field.getType().isArray()) { + int length = Array.getLength(oldValue); + tempOldValue = Array.newInstance(oldValue.getClass().getComponentType(), length); + } + Object tempValue = Optional.ofNullable(getOpcValue(item, field.getType())).orElse(getDefaultPrimitiveValue(field.getType())); + if (LIMIT_CLASS_TYPE_LIST.contains(field.getType())) { + tempValue = getLimitPlacesValue(field.getType(), tempValue).get(field.getType()).get(); + } else if (ARRAY_CLASS_TYPE_LIST.contains(field.getType()) && field.getType().isArray()) { + tempValue = getArrayValue(field.getType(), tempValue).get(field.getType()).get(); + } + Object newValue = Optional.ofNullable(tempValue).orElse(getDefaultPrimitiveValue(field.getType())); + if (ArrayComparisonUtil.equals(newValue, oldValue)) { + continue; + } + if (field.getType().isArray() && oldValue != null && newValue != null) { + int oldValueLength = Array.getLength(oldValue); + int newValueLength = Array.getLength(newValue); + if (oldValueLength == newValueLength) { + for (int i = 0; i < oldValueLength; i++) { + Object newElement = Array.get(newValue, i); + Array.set(oldValue, i, newElement); + } + } else { + ReflectionUtils.setField(field, this, newValue); + } + } else { + ReflectionUtils.setField(field, this, newValue); + } + if (ENABLE_LOGGING_FLAG && !field.getType().isArray()) { + setLog(item.getKey(), newValue, oldValue); + } else if (ENABLE_LOGGING_FLAG && field.getType().isArray()) { + setLog(item.getKey(), ArrayComparisonUtil.arrayToString(newValue), ArrayComparisonUtil.arrayToString(tempOldValue)); + } + lastValues.put(item.getKey(), newValue); + } catch (IllegalAccessException e) { + LOGGER.error("信号读取和赋值时出现异常: {}", e.getMessage() == null ? Arrays.toString(e.getStackTrace()) : e.getMessage()); + } + } + } + + executeLogic(); + + lastValues.forEach((key, value) -> { + String lastFieldName = PRE_LAST + capitalize(key); + Field lastField = fields.get(lastFieldName); + if (lastField != null) { + try { + ReflectionUtils.setField(lastField, this, value); + } catch (Exception e) { + LOGGER.error("信号赋值时出现异常: {}", e.getMessage() == null ? Arrays.toString(e.getStackTrace()) : e.getMessage()); + } + } + }); + } + + & KeyProvider, T> Object getOpcValue(E item, Class type); + + + default void initializeFieldCache(Class clazz) { + FIELD_CACHE.computeIfAbsent(clazz, k -> { + Map fields = new HashMap<>(); + Class currentClass = clazz; + while (currentClass != null) { + for (Field field : currentClass.getDeclaredFields()) { + ReflectionUtils.makeAccessible(field); + fields.put(field.getName(), field); + } + currentClass = currentClass.getSuperclass(); + } + return fields; + }); + } + + + default String capitalize(String str) { + if (str == null || str.isEmpty()) { + return str; + } + return Character.toUpperCase(str.charAt(0)) + str.substring(1); + } + + + void setLog(String key, Object newValue, Object oldValue); + + + void executeLogic(); + + + interface KeyProvider { + String getKey(); + } +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/ItemDto.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/ItemDto.java new file mode 100644 index 0000000..5920e3a --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/ItemDto.java @@ -0,0 +1,28 @@ +package org.nl.acs.device_driver; + +import lombok.Data; + +@Data +public class ItemDto { + private String code; + private String name; + private String db; + private Boolean need_tips; + + public ItemDto(String code, String name, String db) { + this.need_tips = Boolean.FALSE; + this.code = code; + this.name = name; + this.db = db; + } + + public ItemDto(String code, String name, String db, Boolean need_tips) { + this.need_tips = Boolean.FALSE; + this.code = code; + this.name = name; + this.db = db; + this.need_tips = need_tips; + } + + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/basedriver/agv/xg_agv/XianGongAgvDefinition.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/basedriver/agv/xg_agv/XianGongAgvDefinition.java new file mode 100644 index 0000000..8ed8a83 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/basedriver/agv/xg_agv/XianGongAgvDefinition.java @@ -0,0 +1,49 @@ +package org.nl.acs.device_driver.basedriver.agv.xg_agv; + +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.DeviceDriverDefinition; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.LinkedList; +import java.util.List; + +/** + * 仙工AGV驱动 + */ +@Service +public class XianGongAgvDefinition implements DeviceDriverDefinition { + @Override + public String getDriverCode() { + return "xg_agv"; + } + + @Override + public String getDriverName() { + return "标准版-仙工Agv"; + } + + @Override + public String getDriverDescription() { + return "标准版-仙工Agv"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new XianGongAgvDeviceDriver()).setDevice(device).setDriverDefinition(this); + + } + + @Override + public Class getDeviceDriverType() { + return XianGongAgvDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.agv); + return types; + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/basedriver/agv/xg_agv/XianGongAgvDeviceDriver.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/basedriver/agv/xg_agv/XianGongAgvDeviceDriver.java new file mode 100644 index 0000000..adbe03d --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/basedriver/agv/xg_agv/XianGongAgvDeviceDriver.java @@ -0,0 +1,139 @@ +package org.nl.acs.device_driver.basedriver.agv.xg_agv; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.monitor.DeviceStageMonitor; +import org.nl.acs.opc.Device; +import org.nl.modules.wql.util.SpringContextHolder; + +/** + * 仙工AGV + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class XianGongAgvDeviceDriver extends AbstractOpcDeviceDriver implements + DeviceDriver, + ExecutableDeviceDriver, + RouteableDeviceDriver, + DeviceStageMonitor { + + private final InstructionService instructionService = SpringContextHolder.getBean(InstructionService.class); + + /** + * 当前设备号 + */ + private String currentDeviceCode; + + /** + * 当前执行任务号 + */ + private String taskCode = "0"; + + /** + * 电量 + */ + private Double battery_level = 0.0d; + + /** + * 角度 + */ + private Double angle = 0.0d; + + /** + * 当前机器人X坐标 + */ + private Double x = 0.0d; + + /** + * 当前机器人Y坐标 + */ + private Double y = 0.0d; + + /** + * 当前开机时间 ms + */ + private Integer time = 0; + + /** + * 累计运行时间 ms + */ + private Integer total_time = 0; + + /** + * 今日累计行驶里程, 单位 m + */ + private Double today_odo = 0.0d; + + /** + * 累计行驶里程 + */ + private Integer odo = 0; + + /** + * AGV当前状态码 + */ + private Integer status = 0; + + /** + * AGV当前状态对应名称 + */ + private String statusName = this.status == 1 ? "工作中" : this.status == 2 ? "充电中" : this.status == 3 ? "故障" : this.status == 4 ? "休息中" : this.status == 5 ? "关机" : "未知状态"; + + /** + * 当天执行任务数量 + */ + private Integer todayTaskNum = 0; + + /** + * 近一个月执行任务数量 + */ + private Integer monthTaskNum = 0; + + @Override + public Device getDevice() { + return this.device; + } + + @Override + public void execute() throws Exception { + this.currentDeviceCode = this.getDeviceCode(); + this.todayTaskNum = instructionService.findTodayTaskNumByAgvCar(this.currentDeviceCode); + this.monthTaskNum = instructionService.findMonthTaskNumByAgvCar(this.currentDeviceCode); + Thread.sleep(5000); + } + + + @Override + public JSONObject getDeviceStatusName() { + JSONObject jo = new JSONObject(); + jo.put("device_code", this.currentDeviceCode); + jo.put("device_name", this.currentDeviceCode); + jo.put("task_code", this.taskCode); + jo.put("battery_level", (this.battery_level * 100) + "%"); + jo.put("angle", this.angle); + jo.put("time", this.time / 1000 / 1.0 / 3600); + jo.put("total_time", this.total_time / 1000 / 1.0 / 3600); + jo.put("today_odo", this.today_odo); + jo.put("odo", this.odo); + jo.put("x", this.x); + jo.put("y", this.y); + jo.put("status", this.statusName); + //jo.put("status_name", this.statusName); + jo.put("todayTaskNum", this.todayTaskNum); + jo.put("monthTaskNum", this.monthTaskNum); + return jo; + } + + @Override + public void setDeviceStatus(JSONObject data) { + + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/AbstractDeviceDriver.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/AbstractDeviceDriver.java index 58c375a..5142c86 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/AbstractDeviceDriver.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/AbstractDeviceDriver.java @@ -14,6 +14,8 @@ public class AbstractDeviceDriver implements DeviceDriver { private DeviceDriverDefinition driverDefinition; private boolean stop = false; + public boolean online = false; + public AbstractDeviceDriver() { // this.execute_log = new BusinessLoggerImpl(BusinessDomain.device_execute.name()); diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/AbstractOpcDeviceDriver.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/AbstractOpcDeviceDriver.java index 2d4c651..6597585 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/AbstractOpcDeviceDriver.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/AbstractOpcDeviceDriver.java @@ -1,9 +1,16 @@ package org.nl.acs.device_driver.driver; +import com.alibaba.fastjson.JSON; import org.nl.acs.opc.*; import org.nl.acs.udw.UnifiedDataAccessor; import org.nl.acs.udw.UnifiedDataAccessorFactory; import org.nl.acs.udw.UnifiedDataAppService; +import org.nl.acs.udw.mqttUdw.TagDataAccessor; +import org.nl.acs.udw.mqttUdw.factory.TagsDataAccessorFactory; +import org.nl.config.mqtt2.MqttService; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.lucene.service.LuceneExecuteLogService; +import org.nl.modules.lucene.service.dto.LuceneLogDto; import org.nl.modules.wql.exception.WDKException; import org.nl.modules.wql.util.SpringContextHolder; import org.openscada.opc.lib.da.Group; @@ -13,15 +20,19 @@ import org.springframework.beans.factory.annotation.Autowired; import java.lang.reflect.Method; import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class AbstractOpcDeviceDriver extends AbstractDeviceDriver implements OpcDeviceDriver { - UnifiedDataAccessor opcUdw; + + TagDataAccessor opcUdw; @Autowired private OpcServerService opcServerService = SpringContextHolder.getBean(OpcServerService .class); + private final LuceneExecuteLogService luceneExecuteLogService = SpringContextHolder.getBean(LuceneExecuteLogService.class); public AbstractOpcDeviceDriver() { - this.opcUdw = UnifiedDataAccessorFactory.getAccessor(OpcConfig.udw_opc_value_key); + this.opcUdw = TagsDataAccessorFactory.getTagsAccessor(OpcConfig.udw_opc_value_key); } @@ -32,145 +43,93 @@ public class AbstractOpcDeviceDriver extends AbstractDeviceDriver implements Opc private String noLog_last_items; @Override - public UnifiedDataAccessor getOpcValueAccessor() { + public TagDataAccessor getOpcValueAccessor() { return this.opcUdw; } - - public void checkcontrol(Map itemValues) throws Exception { - Group group = opcServerService.getServer(this.getOpcServer()); - Map write = new HashMap(); - Map readitems = new LinkedHashMap(); - List itemsString = new ArrayList(); - itemsString = new ArrayList<> (itemValues.keySet()); - Iterator is = itemsString.iterator(); - - while (is.hasNext()) { - String string = (String) is.next(); - try { - readitems.put(string, group.addItem(string)); - } catch (Exception e) { - e.printStackTrace(); - } - } - int i = 0; - while(true) { - //下发信号 - control( itemValues); - Map read = new HashMap(); - Map itemStatus = group.read(true, (Item[])readitems.values().toArray(new Item[0])); - Set items = itemStatus.keySet(); - Iterator var15 = items.iterator(); - - while(var15.hasNext()) { - Item item = (Item)var15.next(); - ItemState itemState = (ItemState)itemStatus.get(item); - Object value = OpcUtl.getValue(item, itemState); - read.put(item.getId(), value); - } - - boolean check = true; - Iterator var24 = itemsString.iterator(); - - while(var24.hasNext()) { - String itemString = (String)var24.next(); - if (!ObjectUtl.isEquals(itemValues.get(itemString), JsonUtl.parse(read.get(itemString)))) { - check = false; - } - } - if (check) { - return; - } - - if (i > 0) { - ThreadUtl.sleep(300L); - } - - if (i > 3) { - throw new WDKException("写入次数超过3次而失败"); - } - ++i; + /** + * 通过MQTT下发单个电气信号 + * + * @param key + * @param value + */ + public void writing(String key, Object value) { + try { + List> list = new ArrayList<>(); + Map map = new HashMap<>(); + map.put("id", getId() + key); + map.put("v", value); + list.add(map); + MqttService mqttService = SpringContextHolder.getBean(MqttService.class); + mqttService.publishMessage(JSON.toJSONString(list)); + luceneExecuteLogService.deviceExecuteLog(new LuceneLogDto(this.getDevice().getDevice_code(), "下发电气信号 [" + key + ":" + value + "] 成功")); + } catch (Exception e) { + luceneExecuteLogService.deviceExecuteLog(new LuceneLogDto(this.getDevice().getDevice_code(), "下发电气信号 [" + key + ":" + value + "] 失败, 原因:" + e.getMessage())); } } - - public boolean control(Map itemValues) { - - Iterator> it = itemValues.entrySet().iterator(); - - ItemValue p2[]; - p2 = new ItemValue[itemValues.size()]; - int i=0; - while (it.hasNext()) { - Map.Entry entry = it.next(); - System.out.println("即将写入值:"+entry.getKey() + ":" + entry.getValue()); - p2[i] = new ItemValue(); - p2[i].setItem_code(entry.getKey()); - p2[i].setItem_value(entry.getValue()); - i++; + /** + * 通过MQTT下发多个电气信号 + * + * @param key + * @param value + */ + public void writing(List key, List value) { + if (key.size() != value.size()) { + luceneExecuteLogService.deviceExecuteLog(new LuceneLogDto(this.getDevice().getDevice_code(), "下发电气信号 [" + key + "----" + value + "] 失败, 原因:参数长度不一致,不允许下发")); + throw new BadRequestException("参数长度不一致,不允许下发"); + } + Map keys_values = IntStream.range(0, Math.min(key.size(), value.size())) + .boxed() + .collect(Collectors.toMap(key::get, value::get)); + try { + //MQTT下发数据的格式是[ + // {"id":"opc_code.plc_code.device_code.item","v":value}, + // {"id":"opc_code.plc_code.device_code.item","v":value} + // ] + List> list = IntStream.range(0, key.size()) + .mapToObj(i -> new AbstractMap.SimpleEntry<>(key.get(i), value.get(i))) + .map(entry -> { + Map map = new HashMap<>(); + map.put("id", getId() + entry.getKey()); + map.put("v", entry.getValue()); + return map; + }) + .collect(Collectors.toList()); + MqttService mqttService = SpringContextHolder.getBean(MqttService.class); + mqttService.publishMessage(JSON.toJSONString(list)); + luceneExecuteLogService.deviceExecuteLog(new LuceneLogDto(this.getDevice().getDevice_code(), "下发电气信号 [" + JSON.toJSONString(keys_values) + "] 成功")); + } catch (Exception e) { + luceneExecuteLogService.deviceExecuteLog(new LuceneLogDto(this.getDevice().getDevice_code(), "下发电气信号 [" + JSON.toJSONString(keys_values) + "] 失败,原因:" + e.getMessage())); } - - return this.control(p2); } + /** + * 抽取统一下发电气信号前缀 + * + * @return + */ + public String getId() { + return this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + "."; + } + /** + * 下发多个信号key,需与value数量和顺序保持一致 + * + * @param keys + * @return + */ + public List getKeys(String... keys) { + return new ArrayList<>(Arrays.asList(keys)); + } - public boolean control(ItemValue[] itemValues) { - if (itemValues != null && itemValues.length != 0) { - String this_items = JsonUtl.parseWithoutException(itemValues); - boolean need_write = false; - StringBuilder sb = new StringBuilder(); - ItemValue[] var5 = itemValues; - int var6 = itemValues.length; - - for (int var7 = 0; var7 < var6; ++var7) { - ItemValue itemValue = var5[var7]; - String code = itemValue.getItem_code(); - Object udw_value = this.getUdwValue(code); - Object write_value = itemValue.getItem_value(); - sb.append(code); - sb.append(":"); - sb.append(JsonUtl.parseWithoutException(udw_value)); - sb.append(";"); - if (!need_write && !UnifiedDataAppService.isEquals(udw_value, write_value)) { - need_write = true; - } else { - //log.warn("下发信号点位{} 当前写入值:{} 与系统内存值:{} 相同,不再写入 ", code, write_value, udw_value ); - } - } - // need_write = true; - - if (need_write) { - Date date = new Date(); - /*if (StringUtl.isEqual(this_items, this.last_items) && date.getTime() - this.sendTime.getTime() < (long) WcsConfig.opc_write_repeat_check) { - log.trace("发送时间因为小于{}毫秒,而被无视", WcsConfig.opc_write_repeat_check); - return false; - }*/ - - this.last_items = this_items; - this.sendTime = date; - /* this.execute_log.setResource(this.getDevice().getCode(), this.getDevice().getName()); - this.execute_log.log("原始记录{}->变更为{}", new Object[]{sb, this_items}); - OpcServerService opcServerService = OpcServerFactory.getOpcServerService();*/ - - OpcServerService opcServerService = SpringContextHolder.getBean(OpcServerServiceImpl.class); - - opcServerService.writeInteger(this.getOpcServer(), itemValues); - UnifiedDataAccessor opcValueAccessor = this.getOpcValueAccessor(); - ItemValue[] var17 = itemValues; - int var18 = itemValues.length; - - for (int var19 = 0; var19 < var18; ++var19) { - ItemValue itemValue = var17[var19]; - String code = itemValue.getItem_code(); - Object value = itemValue.getItem_value(); - opcValueAccessor.setValue(code, value); - } - } - - return true; - } else { - throw new WDKException("下发 无内容"); - } + /** + * 下发多个电气信号值,需与key数量和顺序保持一致 + * + * @param values + * @return + */ + public List getValues(Object... values) { + return new ArrayList<>(Arrays.asList(values)); } } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/OpcDeviceDriver.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/OpcDeviceDriver.java index 06d046c..ddb8d88 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/OpcDeviceDriver.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/driver/OpcDeviceDriver.java @@ -6,7 +6,7 @@ import com.alibaba.fastjson.JSONObject; import org.nl.acs.device_driver.DeviceDriver; import org.nl.acs.opc.Device; import org.nl.acs.opc.OpcItemDto; -import org.nl.acs.udw.UnifiedDataAccessor; +import org.nl.acs.udw.mqttUdw.TagDataAccessor; import org.nl.modules.wql.core.bean.WQLObject; import java.util.ArrayList; @@ -15,7 +15,7 @@ import java.util.List; import java.util.Map; public interface OpcDeviceDriver extends DeviceDriver { - UnifiedDataAccessor getOpcValueAccessor(); + TagDataAccessor getOpcValueAccessor(); default List getOpcItems() { List returns = new ArrayList(); diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/rgv/ItemProtocol.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/rgv/ItemProtocol.java new file mode 100644 index 0000000..5765435 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/rgv/ItemProtocol.java @@ -0,0 +1,69 @@ +package org.nl.acs.device_driver.rgv; + + +import org.nl.acs.device.device_driver.standard_inspect.ItemDTO; +import org.nl.acs.device_driver.DeviceDriverBaseReader; + +import java.util.ArrayList; +import java.util.List; + +public enum ItemProtocol implements DeviceDriverBaseReader.KeyProvider { + HEARTBEAT("heartbeat", "心跳", "DB1101.B1"), + MODE("mode", "工作模式", "DB1101.B2"), + STATUS("status", "工作状态", "DB1101.B3"), + ERROR("error", "报警信息", "DB1101.B4"), + ENERGY_LEVEL("energyLevel", "当前电量", "DB1101.D5"), + TASK_CODE("taskCode", "当前执行任务号", "DB1101.D6"), + START_DEVICE_CODE("startDeviceCode", "任务起点", "DB1101.S7"), + NEXT_DEVICE_CODE("nextDeviceCode", "任务终点", "DB1101.S8"), + VEHICLE_CODE("vehicleCode", "载具号", "DB1101.S9"), + X("x", "x坐标", "DB1101.D10"), + Y("y", "y坐标", "DB1101.D11"), + ACTION("action", "当前动作", "DB1101.B12"), + TODAY_TASK_NUM("todayTaskNum", "当天执行任务数", "DB1101.D13"), + ALL_TASK_NUM("allTaskNum", "历史执行任务数", "DB1101.D14"); + + private final String key; + private final String description; + private final String address; + + ItemProtocol(String key, String description, String address) { + this.key = key; + this.description = description; + this.address = address; + } + + @Override + public String getKey() { + return this.key; + } + + public String getDescription() { + return description; + } + + public String getAddress() { + return address; + } + + public static List getReadableItemDtos() { + List list = new ArrayList<>(); + for (ItemProtocol prop : values()) { + if (!prop.getKey().startsWith("to")) { + list.add(new ItemDTO(prop.getKey(), prop.getDescription(), prop.getAddress())); + } + } + return list; + } + + public static List getWriteableItemDtos() { + List list = new ArrayList<>(); + for (ItemProtocol prop : values()) { + if (prop.getKey().startsWith("to")) { + list.add(new ItemDTO(prop.getKey(), prop.getDescription(), prop.getAddress())); + } + } + return list; + } + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/rgv/RGVDeviceDriver.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/rgv/RGVDeviceDriver.java new file mode 100644 index 0000000..117b1a6 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/rgv/RGVDeviceDriver.java @@ -0,0 +1,195 @@ +package org.nl.acs.device_driver.rgv; + +import com.alibaba.fastjson.JSONObject; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device_driver.*; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.device_driver.sdk.ItemProtocol; +import org.nl.acs.monitor.DeviceStageMonitor; +import org.nl.modules.lucene.service.LuceneExecuteLogService; +import org.nl.modules.lucene.service.dto.LuceneLogDto; +import org.nl.modules.wql.util.SpringContextHolder; + +/** + * @author zhangjiangwei + */ +@Slf4j +@Getter +@Setter +@RequiredArgsConstructor +public class RGVDeviceDriver extends AbstractOpcDeviceDriver implements + DeviceDriver, + ExecutableDeviceDriver, + RouteableDeviceDriver, + DeviceStageMonitor, + StandardRequestMethod, + DeviceDriverBaseReader { + + private final LuceneExecuteLogService logService = SpringContextHolder.getBean(LuceneExecuteLogService.class); + + /** + * 心跳 + */ + private int heartbeat = 0; + private int lastHeartbeat = 0; + + /** + * 工作模式 + */ + private int mode = 0; + private int lastMode = 0; + + /** + * 工作状态 + */ + private int status = 0; + private int lastStatus = 0; + + /** + * 报警信息 + */ + private int error = 0; + private int lastError = 0; + + /** + * 当前电量 + */ + private Double energyLevel = 0.0d; + private Double lastEnergyLevel = 0.0d; + + /** + * 任务号 + */ + private int taskCode = 0; + private int lastTaskCode = 0; + + /** + * 起点 + */ + private String startDeviceCode; + private String lastStartDeviceCode; + + /** + * 终点 + */ + private String nextDeviceCode; + private String lastNextDeviceCode; + + /** + * 载具号 + */ + private String vehicleCode; + private String lastVehicleCode; + + /** + * x坐标 + */ + private Double x; + private Double lastX; + + /** + * y坐标 + */ + private Double y; + private Double lastY; + + /** + * 当前动作 + */ + private int action = 0; + private int lastAction = 0; + + /** + * 当天执行任务数 + */ + private int todayTaskNum = 0; + private int lastTodayTaskNum = 0; + + /** + * 历史执行任务数 + */ + private int allTaskNum = 0; + private int lastAllTaskNum = 0; + + /** + * 当前设备号 + */ + private String currentDeviceCode; + + /** + * 消息 + */ + private String message = ""; + + /** + * 请求标记相关信息 + */ + private boolean requireSuccess = false; + private long requireTime = System.currentTimeMillis(); + private long requireTimeOut = 5000L; + + /** + * 设备异常标记 + */ + private boolean isError = false; + + + @Override + public & KeyProvider, T> T getOpcValue(E item, Class fieldClassType) { + return (T) this.getValue(item.getKey()); + } + + @Override + public void setLog(String key, Object newValue, Object oldValue) { + logService.deviceExecuteLog(new LuceneLogDto(this.currentDeviceCode, "自动线程读取信号:" + key + ",由" + oldValue + "->" + newValue)); + } + + @Override + public void execute() throws Exception { + this.currentDeviceCode = this.getDevice().getDevice_code(); + this.loadAssignData(currentDeviceCode, ItemProtocol.class); + } + + + private void executeLogicBefore() { + + } + + @Override + public void executeLogic() { + this.executeLogicBefore(); + } + + + @Override + public JSONObject getDeviceStatusName() throws Exception { + JSONObject jo = new JSONObject(); + jo.put("device_code", this.currentDeviceCode); + jo.put("device_name", this.currentDeviceCode); + jo.put("heartbeat", this.heartbeat); + jo.put("mode", this.mode == 1 ? "手动" : this.mode == 2 ? "自动" : "未知"); + jo.put("status", this.error > 0 ? "故障" : this.status == 0 ? "休息中" : this.status == 1 ? "工作中" : this.status == 2 ? "充电中" : "未知状态"); + jo.put("error", this.error); + jo.put("battery_level", (this.energyLevel * 100) + "%"); + jo.put("task_code", this.taskCode); + jo.put("startDeviceCode", this.startDeviceCode); + jo.put("nextDeviceCode", this.nextDeviceCode); + jo.put("vehicleCode", this.vehicleCode); + jo.put("x", this.x); + jo.put("y", this.y); + jo.put("action", this.action); + jo.put("todayTaskNum", this.todayTaskNum); + jo.put("allTaskNum", this.allTaskNum); + return jo; + } + + @Override + public void setDeviceStatus(JSONObject data) { + + } + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/rgv/RGVStationDefinition.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/rgv/RGVStationDefinition.java new file mode 100644 index 0000000..5145998 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/rgv/RGVStationDefinition.java @@ -0,0 +1,60 @@ +package org.nl.acs.device_driver.rgv; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDTO; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.definition.OpcDeviceDriverDefinition; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.LinkedList; +import java.util.List; + +/** + * @author zhangjiangwei + */ +@Service +public class RGVStationDefinition implements OpcDeviceDriverDefinition { + + @Override + public String getDriverCode() { + return "rgv_station"; + } + + @Override + public String getDriverName() { + return "RGV"; + } + + @Override + public String getDriverDescription() { + return "RGV"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return new RGVDeviceDriver().setDevice(device).setDriverDefinition(this); + } + + @Override + public Class getDeviceDriverType() { + return RGVDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList<>(); + types.add(DeviceType.rgv); + return types; + } + + @Override + public List getReadableItemDTOs() { + return ItemProtocol.getReadableItemDtos(); + } + + @Override + public List getWriteableItemDTOs() { + return ItemProtocol.getWriteableItemDtos(); + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/sdk/ItemProtocol.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/sdk/ItemProtocol.java new file mode 100644 index 0000000..c03b9e9 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/sdk/ItemProtocol.java @@ -0,0 +1,56 @@ +package org.nl.acs.device_driver.sdk; + + +import org.nl.acs.device.device_driver.standard_inspect.ItemDTO; +import org.nl.acs.device_driver.DeviceDriverBaseReader; + +import java.util.ArrayList; +import java.util.List; + +public enum ItemProtocol implements DeviceDriverBaseReader.KeyProvider { + MOVE("move", "光电信号", "DB1101.B1"); + + private final String key; + private final String description; + private final String address; + + ItemProtocol(String key, String description, String address) { + this.key = key; + this.description = description; + this.address = address; + } + + @Override + public String getKey() { + return this.key; + } + + public String getDescription() { + return description; + } + + public String getAddress() { + return address; + } + + public static List getReadableItemDtos() { + List list = new ArrayList<>(); + for (ItemProtocol prop : values()) { + if (!prop.getKey().startsWith("to")) { + list.add(new ItemDTO(prop.getKey(), prop.getDescription(), prop.getAddress())); + } + } + return list; + } + + public static List getWriteableItemDtos() { + List list = new ArrayList<>(); + for (ItemProtocol prop : values()) { + if (prop.getKey().startsWith("to")) { + list.add(new ItemDTO(prop.getKey(), prop.getDescription(), prop.getAddress())); + } + } + return list; + } + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/sdk/PhotoelectricDetectionDeviceDriver.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/sdk/PhotoelectricDetectionDeviceDriver.java new file mode 100644 index 0000000..8b1089f --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/sdk/PhotoelectricDetectionDeviceDriver.java @@ -0,0 +1,168 @@ +package org.nl.acs.device_driver.sdk; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.*; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.ext.UnifiedResponse; +import org.nl.acs.ext.wms.data.BaseRequest; +import org.nl.acs.ext.wms.service.AcsToWmsService; +import org.nl.acs.log.service.DeviceExecuteLogService; +import org.nl.acs.monitor.DeviceStageMonitor; +import org.nl.acs.opc.DeviceAppService; +import org.nl.acs.task.service.TaskService; +import org.nl.modules.lucene.service.LuceneExecuteLogService; +import org.nl.modules.lucene.service.dto.LuceneLogDto; +import org.nl.modules.wql.util.SpringContextHolder; + +import java.lang.reflect.InvocationTargetException; + +/** + * @author zhangjiangwei + */ +@Slf4j +@Getter +@Setter +@RequiredArgsConstructor +public class PhotoelectricDetectionDeviceDriver extends AbstractOpcDeviceDriver implements + DeviceDriver, + ExecutableDeviceDriver, + RouteableDeviceDriver, + DeviceStageMonitor, + StandardRequestMethod, + DeviceDriverBaseReader { + + private final DeviceExecuteLogService deviceExecuteLogService = SpringContextHolder.getBean(DeviceExecuteLogService.class); + private final DeviceAppService deviceAppService = SpringContextHolder.getBean(DeviceAppService.class); + private final TaskService taskService = SpringContextHolder.getBean(TaskService.class); + private final DeviceService deviceService = SpringContextHolder.getBean(DeviceService.class); + private final AcsToWmsService acsToWmsService = SpringContextHolder.getBean(AcsToWmsService.class); + private final LuceneExecuteLogService logService = SpringContextHolder.getBean(LuceneExecuteLogService.class); + + + /** + * 光电信号 + */ + private int move = 0; + private int lastMove = 0; + + + private static final int MODE = 3; + + private String currentDeviceCode = null; + private String message = ""; + + + private boolean requireSuccess = false; + private long requireTime = System.currentTimeMillis(); + private long requireTimeOut = 5000L; + + /** + * 设备异常标记 + */ + private boolean isError = false; + + + @Override + public & KeyProvider, T> T getOpcValue(E item, Class fieldClassType) { + return (T) this.getValue(item.getKey()); + } + + @Override + public void setLog(String key, Object newValue, Object oldValue) { + logService.deviceExecuteLog(new LuceneLogDto(this.currentDeviceCode, "自动线程读取信号:" + key + ",由" + oldValue + "->" + newValue)); + } + + @Override + public void execute() throws Exception { + this.currentDeviceCode = this.getDevice().getDevice_code(); + this.loadAssignData(currentDeviceCode, ItemProtocol.class); + } + + + private void executeLogicBefore() { + if (this.move != this.lastMove) { + this.requireSuccess = false; + } + } + + @Override + public void executeLogic() { + this.executeLogicBefore(); + if (!this.isOnline()) { + message = "设备不在线!"; + } else { + if (!requireSuccess) { + Object methodName = this.device.getExtraValue().get(String.valueOf(MODE)); + if (ObjectUtil.isNotEmpty(methodName)) { + try { + this.executionMethodByMode(methodName.toString()); + } catch (Exception e) { + // log.error("{} device driver execute error!", currentDeviceCode); + // log.error(e.getMessage(), e); + String message = "执行工作模式对应方法 " + methodName + " 错误!错误信息:" + e.getMessage(); + this.message = message; + // this.deviceExecuteLogService.deviceExecuteLog(this.currentDeviceCode, "", "", message); + //this.isError = true; + } + } else { + String message = "未知工作模式,驱动未配置对应方法。"; + this.message = message; + //this.deviceExecuteLogService.deviceExecuteLog(this.currentDeviceCode, "", "", message); + } + } + } + } + + private void executionMethodByMode(String methodName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + long currentTimeMillis = System.currentTimeMillis(); + if (currentTimeMillis - this.requireTime < this.requireTimeOut) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.requireTimeOut); + } else { + this.requireTime = currentTimeMillis; + this.getClass().getMethod(methodName).invoke(this); + } + } + + /** + * 申补空托 + * + * @param + */ + @Override + public boolean apply_put_empty_vehicle() { + if (this.move == 0) { + BaseRequest request = new BaseRequest(); + request.setDevice_code(this.currentDeviceCode); + request.setRequest_medthod_code(Thread.currentThread().getStackTrace()[1].getMethodName()); + request.setRequest_medthod_name(RequestMethodEnum.getName(Thread.currentThread().getStackTrace()[1].getMethodName())); + // BaseResponse resp = JSON.toJavaObject(JSONObject.parseObject(this.acsToWmsService.applyTask(request)), BaseResponse.class); + UnifiedResponse response = acsToWmsService.apply(request, JSONObject.class); + this.message = RequestMethodEnum.getName("apply_put_empty_vehicle") + "apply_put_empty_vehicle 接口请求LMS..."; + // logService.deviceExecuteLog(new LuceneLogDto(this.currentDeviceCode, this.message + "参数:" + JSON.toJSONString(request))); + if (response.isSuccess()) { + this.requireSuccess = true; + } + return true; + } + return true; + } + + @Override + public JSONObject getDeviceStatusName() throws Exception { + JSONObject jo = new JSONObject(); + return jo; + } + + @Override + public void setDeviceStatus(JSONObject data) { + + } + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/sdk/PhotoelectricDetectionStationDefinition.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/sdk/PhotoelectricDetectionStationDefinition.java new file mode 100644 index 0000000..6618b8a --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/sdk/PhotoelectricDetectionStationDefinition.java @@ -0,0 +1,60 @@ +package org.nl.acs.device_driver.sdk; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDTO; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.definition.OpcDeviceDriverDefinition; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.LinkedList; +import java.util.List; + +/** + * @author zhangjiangwei + */ +@Service +public class PhotoelectricDetectionStationDefinition implements OpcDeviceDriverDefinition { + + @Override + public String getDriverCode() { + return "photoelectric_detection_station"; + } + + @Override + public String getDriverName() { + return "光电检测站点"; + } + + @Override + public String getDriverDescription() { + return "光电检测站点"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return new PhotoelectricDetectionDeviceDriver().setDevice(device).setDriverDefinition(this); + } + + @Override + public Class getDeviceDriverType() { + return PhotoelectricDetectionDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList<>(); + types.add(DeviceType.station); + return types; + } + + @Override + public List getReadableItemDTOs() { + return ItemProtocol.getReadableItemDtos(); + } + + @Override + public List getWriteableItemDTOs() { + return ItemProtocol.getWriteableItemDtos(); + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/ItemProtocol.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/ItemProtocol.java index fd34a3c..da74bba 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/ItemProtocol.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/ItemProtocol.java @@ -1,81 +1,81 @@ -package org.nl.acs.device_driver.shangdianke; - -import lombok.Getter; -import lombok.Setter; - -/** - * @author zhangjiangwei - */ -@Getter -@Setter -public class ItemProtocol { - - - /** - * 心跳 - */ -// public static final String ITEM_HEARTBEAT = "heartbeat"; - - /** - * 工作模式 - */ -// public static final String ITEM_MODE = "mode"; - - /** - * 光电信号 - */ - public static final String ITEM_MOVE = "move"; - - /** - * 动作信号 - */ -// public static final String ITEM_ACTION = "action"; - - /** - * 报警信号 - */ -// public static final String ITEM_ERROR = "error"; - - /** - * 下发命令 - */ -// public static final String ITEM_TO_COMMAND = "to_command"; - - boolean isOnline; - - private final PhotoelectricDetectionDeviceDriver driver; - - public ItemProtocol(PhotoelectricDetectionDeviceDriver driver) { - this.driver = driver; - } - - public int getOpcIntegerValue(String protocol) { - Integer value = this.driver.getIntegeregerValue(protocol); - if (value == null) { - this.isOnline = false; - return 0; - } else { - this.isOnline = true; - return value; - } - } - -// public int getHeartbeat() { -// return this.getOpcIntegerValue(ItemProtocol.ITEM_HEARTBEAT); +//package org.nl.acs.device_driver.shangdianke; +// +//import lombok.Getter; +//import lombok.Setter; +// +///** +// * @author zhangjiangwei +// */ +//@Getter +//@Setter +//public class ItemProtocol { +// +// +// /** +// * 心跳 +// */ +//// public static final String ITEM_HEARTBEAT = "heartbeat"; +// +// /** +// * 工作模式 +// */ +//// public static final String ITEM_MODE = "mode"; +// +// /** +// * 光电信号 +// */ +// public static final String ITEM_MOVE = "move"; +// +// /** +// * 动作信号 +// */ +//// public static final String ITEM_ACTION = "action"; +// +// /** +// * 报警信号 +// */ +//// public static final String ITEM_ERROR = "error"; +// +// /** +// * 下发命令 +// */ +//// public static final String ITEM_TO_COMMAND = "to_command"; +// +// boolean isOnline; +// +// private final PhotoelectricDetectionDeviceDriver driver; +// +// public ItemProtocol(PhotoelectricDetectionDeviceDriver driver) { +// this.driver = driver; // } -// public int getMode() { -// return this.getOpcIntegerValue(ItemProtocol.ITEM_MODE); +// +// public int getOpcIntegerValue(String protocol) { +// Integer value = this.driver.getIntegeregerValue(protocol); +// if (value == null) { +// this.isOnline = false; +// return 0; +// } else { +// this.isOnline = true; +// return value; +// } // } - public int getMove() { - return this.getOpcIntegerValue(ItemProtocol.ITEM_MOVE); - } -// public int getAction() { -// return this.getOpcIntegerValue(ItemProtocol.ITEM_ACTION); +// +//// public int getHeartbeat() { +//// return this.getOpcIntegerValue(ItemProtocol.ITEM_HEARTBEAT); +//// } +//// public int getMode() { +//// return this.getOpcIntegerValue(ItemProtocol.ITEM_MODE); +//// } +// public int getMove() { +// return this.getOpcIntegerValue(ItemProtocol.ITEM_MOVE); // } -// public int getError() { -// return this.getOpcIntegerValue(ItemProtocol.ITEM_ERROR); -// } -// public int getToCommand() { -// return this.getOpcIntegerValue(ItemProtocol.ITEM_TO_COMMAND); -// } -} +//// public int getAction() { +//// return this.getOpcIntegerValue(ItemProtocol.ITEM_ACTION); +//// } +//// public int getError() { +//// return this.getOpcIntegerValue(ItemProtocol.ITEM_ERROR); +//// } +//// public int getToCommand() { +//// return this.getOpcIntegerValue(ItemProtocol.ITEM_TO_COMMAND); +//// } +//} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionDeviceDriver.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionDeviceDriver.java index 8bb7cae..76965e9 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionDeviceDriver.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionDeviceDriver.java @@ -1,200 +1,200 @@ -package org.nl.acs.device_driver.shangdianke; - -import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.nl.acs.device.service.DeviceService; -import org.nl.acs.device_driver.*; -import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; -import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; -import org.nl.acs.ext.wms.data.BaseRequest; -import org.nl.acs.ext.wms.data.BaseResponse; -import org.nl.acs.ext.wms.service.AcsToWmsService; -import org.nl.acs.log.service.DeviceExecuteLogService; -import org.nl.acs.monitor.DeviceStageMonitor; -import org.nl.acs.opc.DeviceAppService; -import org.nl.acs.task.service.TaskService; -import org.nl.modules.lucene.service.LuceneExecuteLogService; -import org.nl.modules.lucene.service.dto.LuceneLogDto; -import org.nl.modules.wql.util.SpringContextHolder; - -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Map; - -/** - * @author zhangjiangwei - */ -@Slf4j -@Getter -@Setter -@RequiredArgsConstructor -public class PhotoelectricDetectionDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver, DeviceStageMonitor, StandardRequestMethod, HeartbeatableDeviceDriver { - - /** - * 心跳 - */ -// private int heartbeat = 0; -// private int lastHeartbeat = this.heartbeat; - - /** - * 工作模式 - */ -// private int mode = 0; -// private int lastMode = this.mode; - - /** - * 光电信号 - */ - private int move = 0; - private int lastMove = 0; - - /** - * 动作信号 - */ -// private int action = 0; -// private int lastAction = this.action; - - /** - * 报警信号 - */ -// private int error = 0; -// private int lastError = this.error; - - /** - * 下发命令 - */ -// private int toCommand = 0; -// private int lastToCommand = this.toCommand; - - private static final int MODE = 3; - - private String currentDeviceCode = null; - private boolean isOnline = false; - private boolean isError = false; - private String message = ""; - - private final ItemProtocol itemProtocol = new ItemProtocol(this); - - private boolean requireSuccess = false; - private long requireTime = System.currentTimeMillis(); - private long requireTimeOut = 10000L; - - private final DeviceExecuteLogService deviceExecuteLogService = SpringContextHolder.getBean(DeviceExecuteLogService.class); - private final DeviceAppService deviceAppService = SpringContextHolder.getBean(DeviceAppService.class); - private final TaskService taskService = SpringContextHolder.getBean(TaskService.class); - private final DeviceService deviceService = SpringContextHolder.getBean(DeviceService.class); - private final LuceneExecuteLogService lucene = SpringContextHolder.getBean(LuceneExecuteLogService.class); - private final AcsToWmsService acsToWmsService = SpringContextHolder.getBean(AcsToWmsService.class); - - @Override - public void execute() throws Exception { - this.message = ""; - - try { - this.currentDeviceCode = this.getDeviceCode(); -// this.heartbeat = this.itemProtocol.getHeartbeat(); -// this.mode = this.itemProtocol.getMode(); - this.move = this.itemProtocol.getMove(); -// this.action = this.itemProtocol.getAction(); -// this.error = this.itemProtocol.getError(); -// this.toCommand = this.itemProtocol.getToCommand(); - - if (this.move != this.lastMove) { - if (move == 0) { - requireSuccess = false; - } - } - -// if (mode > 0 && !requireSuccess) { - if (!requireSuccess) { - Object methodName = this.device.getExtraValue().get(String.valueOf(MODE)); - if (ObjectUtil.isNotEmpty(methodName)) { - try { - this.executionMethodByMode(methodName.toString()); - } catch (Exception e) { - log.error("{} device driver execute error!", currentDeviceCode); - log.error(e.getMessage(), e); - String message = "执行工作模式对应方法 " + methodName + " 错误!错误信息:" + e.getMessage(); - this.message = message; - this.deviceExecuteLogService.deviceExecuteLog(this.currentDeviceCode, "", "", message); - this.isError = true; - } - } else { - String message = "未知工作模式,驱动未配置对应方法。"; - this.message = message; - this.deviceExecuteLogService.deviceExecuteLog(this.currentDeviceCode, "", "", message); - } - } - - } catch (Exception e) { - log.error("{} device driver execute error!", currentDeviceCode); - log.error(e.getMessage(), e); - return; - } -// this.lastHeartbeat = this.heartbeat; -// this.lastMode = this.mode; - this.lastMove = this.move; -// this.lastAction = this.action; -// this.lastError = this.error; -// this.lastToCommand = this.toCommand; - } - - private void executionMethodByMode(String methodName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - long currentTimeMillis = System.currentTimeMillis(); - if (currentTimeMillis - this.requireTime < this.requireTimeOut) { - log.trace("触发时间因为小于{}毫秒,而被无视", this.requireTimeOut); - } else { - this.requireTime = currentTimeMillis; - this.getClass().getMethod(methodName).invoke(this); - } - } - - /** - * 申补空托 - * - * @param - */ - @Override - public boolean apply_put_empty_vehicle() { - if (move == 0) { - BaseRequest request = new BaseRequest(); - request.setDevice_code(this.currentDeviceCode); - request.setRequest_medthod_code(Thread.currentThread().getStackTrace()[1].getMethodName()); - request.setRequest_medthod_name(RequestMethodEnum.getName(Thread.currentThread().getStackTrace()[1].getMethodName())); - BaseResponse resp = JSON.toJavaObject(JSONObject.parseObject(acsToWmsService.applyTask(request)), BaseResponse.class); - message = RequestMethodEnum.getName("apply_put_empty_vehicle") + "apply_put_empty_vehicle 接口请求LMS..."; - lucene.deviceExecuteLog(new LuceneLogDto(this.currentDeviceCode, message + "参数:" + JSON.toJSONString(request))); - if (resp.isOk()) { - this.requireSuccess = true; - } - return true; - } - return true; - } - - @Override - public JSONObject getDeviceStatusName() throws Exception { - return null; - } - - @Override - public void setDeviceStatus(JSONObject data) { - - } - - public void writing(String param, Object value) { - String to_param = this.getDevice().getOpc_server_code() + "." + - this.getDevice().getOpc_plc_code() + "." + - this.getDevice().getDevice_code() + "." + - param; - - Map itemMap = new HashMap<>(); - itemMap.put(to_param, value); - this.control(itemMap); - } -} +//package org.nl.acs.device_driver.shangdianke; +// +//import cn.hutool.core.util.ObjectUtil; +//import com.alibaba.fastjson.JSON; +//import com.alibaba.fastjson.JSONObject; +//import lombok.Getter; +//import lombok.RequiredArgsConstructor; +//import lombok.Setter; +//import lombok.extern.slf4j.Slf4j; +//import org.nl.acs.device.service.DeviceService; +//import org.nl.acs.device_driver.*; +//import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +//import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +//import org.nl.acs.ext.wms.data.BaseRequest; +//import org.nl.acs.ext.wms.data.BaseResponse; +//import org.nl.acs.ext.wms.service.AcsToWmsService; +//import org.nl.acs.log.service.DeviceExecuteLogService; +//import org.nl.acs.monitor.DeviceStageMonitor; +//import org.nl.acs.opc.DeviceAppService; +//import org.nl.acs.task.service.TaskService; +//import org.nl.modules.lucene.service.LuceneExecuteLogService; +//import org.nl.modules.lucene.service.dto.LuceneLogDto; +//import org.nl.modules.wql.util.SpringContextHolder; +// +//import java.lang.reflect.InvocationTargetException; +//import java.util.HashMap; +//import java.util.Map; +// +///** +// * @author zhangjiangwei +// */ +//@Slf4j +//@Getter +//@Setter +//@RequiredArgsConstructor +//public class PhotoelectricDetectionDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver, DeviceStageMonitor, StandardRequestMethod, HeartbeatableDeviceDriver { +// +// /** +// * 心跳 +// */ +//// private int heartbeat = 0; +//// private int lastHeartbeat = this.heartbeat; +// +// /** +// * 工作模式 +// */ +//// private int mode = 0; +//// private int lastMode = this.mode; +// +// /** +// * 光电信号 +// */ +// private int move = 0; +// private int lastMove = 0; +// +// /** +// * 动作信号 +// */ +//// private int action = 0; +//// private int lastAction = this.action; +// +// /** +// * 报警信号 +// */ +//// private int error = 0; +//// private int lastError = this.error; +// +// /** +// * 下发命令 +// */ +//// private int toCommand = 0; +//// private int lastToCommand = this.toCommand; +// +// private static final int MODE = 3; +// +// private String currentDeviceCode = null; +// private boolean isOnline = false; +// private boolean isError = false; +// private String message = ""; +// +// private final ItemProtocol itemProtocol = new ItemProtocol(this); +// +// private boolean requireSuccess = false; +// private long requireTime = System.currentTimeMillis(); +// private long requireTimeOut = 10000L; +// +// private final DeviceExecuteLogService deviceExecuteLogService = SpringContextHolder.getBean(DeviceExecuteLogService.class); +// private final DeviceAppService deviceAppService = SpringContextHolder.getBean(DeviceAppService.class); +// private final TaskService taskService = SpringContextHolder.getBean(TaskService.class); +// private final DeviceService deviceService = SpringContextHolder.getBean(DeviceService.class); +// private final LuceneExecuteLogService lucene = SpringContextHolder.getBean(LuceneExecuteLogService.class); +// private final AcsToWmsService acsToWmsService = SpringContextHolder.getBean(AcsToWmsService.class); +// +// @Override +// public void execute() throws Exception { +// this.message = ""; +// +// try { +// this.currentDeviceCode = this.getDeviceCode(); +//// this.heartbeat = this.itemProtocol.getHeartbeat(); +//// this.mode = this.itemProtocol.getMode(); +// this.move = this.itemProtocol.getMove(); +//// this.action = this.itemProtocol.getAction(); +//// this.error = this.itemProtocol.getError(); +//// this.toCommand = this.itemProtocol.getToCommand(); +// +// if (this.move != this.lastMove) { +// if (move == 0) { +// requireSuccess = false; +// } +// } +// +//// if (mode > 0 && !requireSuccess) { +// if (!requireSuccess) { +// Object methodName = this.device.getExtraValue().get(String.valueOf(MODE)); +// if (ObjectUtil.isNotEmpty(methodName)) { +// try { +// this.executionMethodByMode(methodName.toString()); +// } catch (Exception e) { +// log.error("{} device driver execute error!", currentDeviceCode); +// log.error(e.getMessage(), e); +// String message = "执行工作模式对应方法 " + methodName + " 错误!错误信息:" + e.getMessage(); +// this.message = message; +// this.deviceExecuteLogService.deviceExecuteLog(this.currentDeviceCode, "", "", message); +// this.isError = true; +// } +// } else { +// String message = "未知工作模式,驱动未配置对应方法。"; +// this.message = message; +// this.deviceExecuteLogService.deviceExecuteLog(this.currentDeviceCode, "", "", message); +// } +// } +// +// } catch (Exception e) { +// log.error("{} device driver execute error!", currentDeviceCode); +// log.error(e.getMessage(), e); +// return; +// } +//// this.lastHeartbeat = this.heartbeat; +//// this.lastMode = this.mode; +// this.lastMove = this.move; +//// this.lastAction = this.action; +//// this.lastError = this.error; +//// this.lastToCommand = this.toCommand; +// } +// +// private void executionMethodByMode(String methodName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { +// long currentTimeMillis = System.currentTimeMillis(); +// if (currentTimeMillis - this.requireTime < this.requireTimeOut) { +// log.trace("触发时间因为小于{}毫秒,而被无视", this.requireTimeOut); +// } else { +// this.requireTime = currentTimeMillis; +// this.getClass().getMethod(methodName).invoke(this); +// } +// } +// +// /** +// * 申补空托 +// * +// * @param +// */ +// @Override +// public boolean apply_put_empty_vehicle() { +// if (move == 0) { +// BaseRequest request = new BaseRequest(); +// request.setDevice_code(this.currentDeviceCode); +// request.setRequest_medthod_code(Thread.currentThread().getStackTrace()[1].getMethodName()); +// request.setRequest_medthod_name(RequestMethodEnum.getName(Thread.currentThread().getStackTrace()[1].getMethodName())); +// BaseResponse resp = JSON.toJavaObject(JSONObject.parseObject(acsToWmsService.applyTask(request)), BaseResponse.class); +// message = RequestMethodEnum.getName("apply_put_empty_vehicle") + "apply_put_empty_vehicle 接口请求LMS..."; +// lucene.deviceExecuteLog(new LuceneLogDto(this.currentDeviceCode, message + "参数:" + JSON.toJSONString(request))); +// if (resp.isOk()) { +// this.requireSuccess = true; +// } +// return true; +// } +// return true; +// } +// +// @Override +// public JSONObject getDeviceStatusName() throws Exception { +// return null; +// } +// +// @Override +// public void setDeviceStatus(JSONObject data) { +// +// } +// +// public void writing(String param, Object value) { +// String to_param = this.getDevice().getOpc_server_code() + "." + +// this.getDevice().getOpc_plc_code() + "." + +// this.getDevice().getDevice_code() + "." + +// param; +// +// Map itemMap = new HashMap<>(); +// itemMap.put(to_param, value); +// this.control(itemMap); +// } +//} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionStationDefinition.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionStationDefinition.java index 5510cbb..422d32f 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionStationDefinition.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionStationDefinition.java @@ -1,69 +1,69 @@ -package org.nl.acs.device_driver.shangdianke; - -import org.nl.acs.device.device_driver.standard_inspect.ItemDTO; -import org.nl.acs.device_driver.DeviceDriver; -import org.nl.acs.device_driver.definition.OpcDeviceDriverDefinition; -import org.nl.acs.opc.Device; -import org.nl.acs.opc.DeviceType; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -/** - * @author zhangjiangwei - */ -@Service -public class PhotoelectricDetectionStationDefinition implements OpcDeviceDriverDefinition { - - @Override - public String getDriverCode() { - return "photoelectric_detection_station"; - } - - @Override - public String getDriverName() { - return "光电检测站点"; - } - - @Override - public String getDriverDescription() { - return "光电检测站点"; - } - - @Override - public DeviceDriver getDriverInstance(Device device) { - return new PhotoelectricDetectionDeviceDriver().setDevice(device).setDriverDefinition(this); - } - - @Override - public Class getDeviceDriverType() { - return PhotoelectricDetectionDeviceDriver.class; - } - - @Override - public List getFitDeviceTypes() { - List types = new LinkedList<>(); - types.add(DeviceType.station); - return types; - } - - @Override - public List getReadableItemDTOs() { - ArrayList itemDTOs = new ArrayList<>(); -// itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_HEARTBEAT, "心跳", "")); -// itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_MODE, "工作模式", "")); - itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_MOVE, "光电信号", "")); -// itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_ACTION, "动作信号", "")); -// itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_ERROR, "报警信号", "")); - return itemDTOs; - } - - @Override - public List getWriteableItemDTOs() { - ArrayList itemDTOs = new ArrayList<>(); -// itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_TO_COMMAND, "下发命令", "")); - return itemDTOs; - } -} +//package org.nl.acs.device_driver.shangdianke; +// +//import org.nl.acs.device.device_driver.standard_inspect.ItemDTO; +//import org.nl.acs.device_driver.DeviceDriver; +//import org.nl.acs.device_driver.definition.OpcDeviceDriverDefinition; +//import org.nl.acs.opc.Device; +//import org.nl.acs.opc.DeviceType; +//import org.springframework.stereotype.Service; +// +//import java.util.ArrayList; +//import java.util.LinkedList; +//import java.util.List; +// +///** +// * @author zhangjiangwei +// */ +//@Service +//public class PhotoelectricDetectionStationDefinition implements OpcDeviceDriverDefinition { +// +// @Override +// public String getDriverCode() { +// return "photoelectric_detection_station"; +// } +// +// @Override +// public String getDriverName() { +// return "光电检测站点"; +// } +// +// @Override +// public String getDriverDescription() { +// return "光电检测站点"; +// } +// +// @Override +// public DeviceDriver getDriverInstance(Device device) { +// return new PhotoelectricDetectionDeviceDriver().setDevice(device).setDriverDefinition(this); +// } +// +// @Override +// public Class getDeviceDriverType() { +// return PhotoelectricDetectionDeviceDriver.class; +// } +// +// @Override +// public List getFitDeviceTypes() { +// List types = new LinkedList<>(); +// types.add(DeviceType.station); +// return types; +// } +// +// @Override +// public List getReadableItemDTOs() { +// ArrayList itemDTOs = new ArrayList<>(); +//// itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_HEARTBEAT, "心跳", "")); +//// itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_MODE, "工作模式", "")); +// itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_MOVE, "光电信号", "")); +//// itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_ACTION, "动作信号", "")); +//// itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_ERROR, "报警信号", "")); +// return itemDTOs; +// } +// +// @Override +// public List getWriteableItemDTOs() { +// ArrayList itemDTOs = new ArrayList<>(); +//// itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_TO_COMMAND, "下发命令", "")); +// return itemDTOs; +// } +//} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/utils/ArrayComparisonUtil.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/utils/ArrayComparisonUtil.java new file mode 100644 index 0000000..a7c6928 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/utils/ArrayComparisonUtil.java @@ -0,0 +1,77 @@ +package org.nl.acs.device_driver.utils; + +import cn.hutool.core.util.ObjectUtil; + +import java.util.Arrays; +import java.util.Objects; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/4/7 + */ +public class ArrayComparisonUtil { + public static boolean equals(Object oldValue, Object newValue) { + + if ((oldValue instanceof String && newValue == null && "".equals(oldValue)) || + (newValue instanceof String && oldValue == null && "".equals(newValue))) { + return true; + } + if (oldValue == null || newValue == null) { + return ObjectUtil.equals(oldValue, newValue); + } + Class oldType = oldValue.getClass(); + Class newType = newValue.getClass(); + if (oldType.isArray() && newType.isArray()) { + if (oldType.getComponentType().isArray() || newType.getComponentType().isArray()) { + return Arrays.deepEquals(new Object[]{newValue}, new Object[]{oldValue}); + } else { + if (oldValue instanceof Object[] && newValue instanceof Object[]) { + return Arrays.deepEquals((Object[]) oldValue, (Object[]) newValue); + } else if (oldValue instanceof int[] && newValue instanceof int[]) { + return Arrays.equals((int[]) oldValue, (int[]) newValue); + } else if (oldValue instanceof long[] && newValue instanceof long[]) { + return Arrays.equals((long[]) oldValue, (long[]) newValue); + } else if (oldValue instanceof short[] && newValue instanceof short[]) { + return Arrays.equals((short[]) oldValue, (short[]) newValue); + } else if (oldValue instanceof char[] && newValue instanceof char[]) { + return Arrays.equals((char[]) oldValue, (char[]) newValue); + } else if (oldValue instanceof byte[] && newValue instanceof byte[]) { + return Arrays.equals((byte[]) oldValue, (byte[]) newValue); + } else if (oldValue instanceof boolean[] && newValue instanceof boolean[]) { + return Arrays.equals((boolean[]) oldValue, (boolean[]) newValue); + } else if (oldValue instanceof float[] && newValue instanceof float[]) { + return Arrays.equals((float[]) oldValue, (float[]) newValue); + } else if (oldValue instanceof double[] && newValue instanceof double[]) { + return Arrays.equals((double[]) oldValue, (double[]) newValue); + } + } + } + return ObjectUtil.equals(oldValue, newValue); + } + + public static String arrayToString(Object array) { + if (array instanceof int[]) { + return Arrays.toString((int[]) array); + } else if (array instanceof double[]) { + return Arrays.toString((double[]) array); + } else if (array instanceof long[]) { + return Arrays.toString((long[]) array); + } else if (array instanceof char[]) { + return Arrays.toString((char[]) array); + } else if (array instanceof float[]) { + return Arrays.toString((float[]) array); + } else if (array instanceof boolean[]) { + return Arrays.toString((boolean[]) array); + } else if (array instanceof byte[]) { + return Arrays.toString((byte[]) array); + } else if (array instanceof short[]) { + return Arrays.toString((short[]) array); + } else if (array instanceof Object[]) { + return Arrays.deepToString((Object[]) array); + } else { + return Objects.toString(array, "null"); + } + } + +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/utils/ArrayConverter.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/utils/ArrayConverter.java new file mode 100644 index 0000000..ff6ee36 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/utils/ArrayConverter.java @@ -0,0 +1,191 @@ +package org.nl.acs.device_driver.utils; + +import org.nl.config.mqtt2.TagsUtil; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Arrays; +import java.util.function.Function; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/4/7 + */ +public interface ArrayConverter { + + static String replaceArrString(String value) { + return value.replaceAll("\\[|\\]", "").trim(); + } + + static int[] convertStringToArrayOfInt(String value) { + return Arrays.stream(preprocessInputString(value)) + .filter(s -> !s.isEmpty()) + .mapToInt(Integer::parseInt) + .toArray(); + } + + static Integer[] convertStringToArrayOfIntegerObject(String value) { + return Arrays.stream(preprocessInputString(value)) + .filter(s -> !s.isEmpty()) + .map(Integer::valueOf) + .toArray(Integer[]::new); + } + + static short[] convertStringToArrayOfShort(String value) { + String[] processed = preprocessInputString(value); + if (processed.length == 0) { + return new short[0]; + } + + short[] result = new short[processed.length]; + for (int i = 0; i < processed.length; i++) { + result[i] = Short.parseShort(processed[i].trim()); + } + return result; + } + + static Short[] convertStringToArrayOfShortObject(String value) { + return Arrays.stream(preprocessInputString(value)) + .filter(s -> !s.isEmpty()) + .map(s -> Short.parseShort(s.trim())) + .toArray(Short[]::new); + } + + static byte[] convertStringToArrayOfByte(String value) { + String[] processed = preprocessInputString(value); + if (processed.length == 0) { + return new byte[0]; + } + byte[] result = new byte[processed.length]; + for (int i = 0; i < processed.length; i++) { + result[i] = Byte.parseByte(processed[i].trim()); + } + return result; + } + + static Byte[] convertStringToArrayOfByteObject(String value) { + return Arrays.stream(preprocessInputString(value)) + .filter(s -> !s.isEmpty()) + .map(s -> Byte.parseByte(s.trim())) + .toArray(Byte[]::new); + } + + static long[] convertStringToArrayOfLong(String value) { + return Arrays.stream(preprocessInputString(value)) + .filter(s -> !s.isEmpty()) + .mapToLong(Long::parseLong) + .toArray(); + } + + static Long[] convertStringToArrayOfLongObject(String value) { + return Arrays.stream(preprocessInputString(value)) + .filter(s -> !s.isEmpty()) + .map(Long::valueOf) + .toArray(Long[]::new); + } + + static char[] convertStringToArrayOfChar(String value) { + if (value == null) { + return new char[0]; + } + return value.toCharArray(); + } + + public static Character[] convertStringToArrayOfCharacterObject(String value) { + if (value == null || value.isEmpty()) { + return new Character[0]; + } + return value.chars() + .mapToObj(c -> (char) c) + .toArray(Character[]::new); + } + + + static boolean[] convertStringToArrayOfBoolean(String value) { + String[] processed = preprocessInputString(value); + if (processed.length == 0) { + return new boolean[0]; + } + boolean[] result = new boolean[processed.length]; + for (int i = 0; i < processed.length; i++) { + result[i] = Boolean.parseBoolean(processed[i].trim()); + } + return result; + } + + static Boolean[] convertStringToArrayOfBooleanObject(String value) { + return Arrays.stream(preprocessInputString(value)) + .filter(s -> !s.isEmpty()) + .map(Boolean::valueOf) + .toArray(Boolean[]::new); + } + + static String[] convertStringToArrayOfString(String value) { + String[] stringArrays = preprocessInputString(value); + return Arrays.stream(stringArrays) + .map(s -> s.replaceAll("^\"|\"$", "")) + .toArray(String[]::new); + } + + static String[] preprocessInputString(String value) { + if (value == null || value.isEmpty() || value.matches("\\[?\\]?")) { + return new String[0]; + } + return value.replace("[", "").replace("]", "").split(","); + } + + static float[] convertStringToArrayOfFloat(String value, PrecisionLimiter limiter) { + Double[] intermediate = Arrays.stream(replaceArrString(value).split(",")) + .filter(s -> !s.isEmpty()) + .map(String::trim) + .map(s -> s.replaceAll("\"", "")) + .map(s -> limiter.apply(s).doubleValue()) + .toArray(Double[]::new); + float[] result = new float[intermediate.length]; + for (int i = 0; i < intermediate.length; i++) { + result[i] = intermediate[i].floatValue(); + } + return result; + } + + static Float[] convertStringToArrayOfFloatObject(String value, PrecisionLimiter limiter) { + return Arrays.stream(replaceArrString(value).split(",")) + .filter(s -> !s.isEmpty()) + .map(String::trim) + .map(s -> s.replaceAll("\"", "")) + .map(s -> Float.valueOf(limiter.apply(s).floatValue())) + .toArray(Float[]::new); + } + + static double[] convertStringToArrayOfDouble(String value, PrecisionLimiter limiter) { + return Arrays.stream(replaceArrString(value).split(",")) + .filter(s -> !s.isEmpty()) + .map(String::trim) + .map(s -> s.replaceAll("\"", "")) + .mapToDouble(s -> limiter.apply(s).doubleValue()) + .toArray(); + } + + static Double[] convertStringToArrayOfDoubleObject(String value, PrecisionLimiter limiter) { + return Arrays.stream(replaceArrString(value).split(",")) + .filter(s -> !s.isEmpty()) + .map(String::trim) + .map(s -> s.replaceAll("\"", "")) + .map(s -> Double.valueOf(limiter.apply(s).doubleValue())) + .toArray(Double[]::new); + } + + + static float limitFloatPlaces(String value) { + return BigDecimal.valueOf(Float.parseFloat(value)).setScale(TagsUtil.SCALE, RoundingMode.HALF_DOWN).floatValue(); + } + + static double limitDoublePlaces(String value) { + return BigDecimal.valueOf(Double.parseDouble(value)).setScale(TagsUtil.SCALE, RoundingMode.HALF_DOWN).doubleValue(); + } + + @FunctionalInterface + interface PrecisionLimiter extends Function { + } +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/RequestAdapter.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/RequestAdapter.java new file mode 100644 index 0000000..a94136b --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/RequestAdapter.java @@ -0,0 +1,10 @@ +package org.nl.acs.ext; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/4/22 + */ +public interface RequestAdapter { + String getUrl(); +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/ResponseAdapter.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/ResponseAdapter.java new file mode 100644 index 0000000..b28363f --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/ResponseAdapter.java @@ -0,0 +1,12 @@ +package org.nl.acs.ext; + + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/4/22 + */ +public interface ResponseAdapter { + public UnifiedResponse adapt(String responseBody, Class type); +} + diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/UnifiedResponse.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/UnifiedResponse.java new file mode 100644 index 0000000..d920da5 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/UnifiedResponse.java @@ -0,0 +1,37 @@ +package org.nl.acs.ext; + + +public class UnifiedResponse { + private boolean success; + private String message; + private T data; + + public UnifiedResponse(boolean success, String message, T data) { + this.success = success; + this.message = message; + this.data = data; + } + + + public UnifiedResponse(boolean success, String message) { + this.success = success; + this.message = message; + } + + public boolean isSuccess() { + return this.success; + } + + public String getMessage() { + return this.message; + } + + public T getData() { + return this.data; + } + + public void setData(T data) { + this.data = data; + } +} + diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/OtherToInterfaceLogAspect.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/OtherToInterfaceLogAspect.java new file mode 100644 index 0000000..5eb9d8e --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/OtherToInterfaceLogAspect.java @@ -0,0 +1,93 @@ +package org.nl.acs.ext.log; + +import com.alibaba.fastjson.JSON; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.nl.acs.ext.wms.IpUtil; +import org.nl.modules.lucene.service.LuceneExecuteLogService; +import org.nl.modules.lucene.service.dto.LuceneLogDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.*; + +import java.lang.reflect.Method; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/7/8 + */ +@Aspect +@Component +public class OtherToInterfaceLogAspect { + + @Autowired + private LuceneExecuteLogService logService; + + @Around("@annotation(org.nl.acs.ext.log.OthersToInterfaceLog)") + public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { + long startTime = System.currentTimeMillis(); + + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + + Class targetClass = joinPoint.getTarget().getClass(); + RequestMapping classRequestMapping = targetClass.getAnnotation(RequestMapping.class); + String classUrlValue = classRequestMapping != null ? String.join(",", classRequestMapping.value()) : "No Class Annotation"; + + String methodUrlValue = ""; + if (method.isAnnotationPresent(GetMapping.class)) { + GetMapping getMapping = method.getAnnotation(GetMapping.class); + methodUrlValue = String.join(",", getMapping.value()); + } else if (method.isAnnotationPresent(PostMapping.class)) { + PostMapping postMapping = method.getAnnotation(PostMapping.class); + methodUrlValue = String.join(",", postMapping.value()); + } else if (method.isAnnotationPresent(PutMapping.class)) { + PutMapping putMapping = method.getAnnotation(PutMapping.class); + methodUrlValue = String.join(",", putMapping.value()); + } else if (method.isAnnotationPresent(DeleteMapping.class)) { + DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class); + methodUrlValue = String.join(",", deleteMapping.value()); + } else if (method.isAnnotationPresent(RequestMapping.class)) { + RequestMapping methodRequestMapping = method.getAnnotation(RequestMapping.class); + methodUrlValue = String.join(",", methodRequestMapping.value()); + } + String request_direction = ""; + if (method.isAnnotationPresent(OthersToInterfaceLog.class)) { + OthersToInterfaceLog interfaceLog = method.getAnnotation(OthersToInterfaceLog.class); + request_direction = interfaceLog.value(); + } + + String methodName = joinPoint.getSignature().getName(); + Object[] args = joinPoint.getArgs(); + + LuceneLogDto logDto = + LuceneLogDto.builder() + .logType("接口日志") + .request_url(IpUtil.localIP() + classUrlValue + methodUrlValue) + .request_direction(request_direction) + .request_param(JSON.toJSONString(args)) + .method(methodName) + .content("开始请求") + .build(); + logService.interfaceExecuteLog(logDto); + + Object result = joinPoint.proceed(); + + logDto = + LuceneLogDto.builder() + .logType("接口日志") + .request_url(IpUtil.localIP() + classUrlValue + methodUrlValue) + .request_direction(request_direction) + .request_param(JSON.toJSONString(args)) + .method(methodName) + .response_param(JSON.toJSONString(result)) + .executeTime(System.currentTimeMillis() - startTime) + .content("响应请求") + .build(); + logService.interfaceExecuteLog(logDto); + return result; + } +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/OthersToInterfaceLog.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/OthersToInterfaceLog.java new file mode 100644 index 0000000..6c4afbb --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/OthersToInterfaceLog.java @@ -0,0 +1,12 @@ +package org.nl.acs.ext.log; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface OthersToInterfaceLog { + String value() default ""; +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/ToOtherInterfaceLogAspect.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/ToOtherInterfaceLogAspect.java new file mode 100644 index 0000000..4793750 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/ToOtherInterfaceLogAspect.java @@ -0,0 +1,123 @@ +package org.nl.acs.ext.log; + +import com.alibaba.fastjson.JSON; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.nl.modules.lucene.service.LuceneExecuteLogService; +import org.nl.modules.lucene.service.dto.LuceneLogDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/7/8 + */ +@Aspect +@Component +public class ToOtherInterfaceLogAspect { + + private static final ConcurrentMap, Field> fieldCache = new ConcurrentHashMap<>(); + private static final ConcurrentMap, Method> methodCache = new ConcurrentHashMap<>(); + + @Autowired + private LuceneExecuteLogService logService; + + @Around("@annotation(org.nl.acs.ext.log.ToOthersInterfaceLog)") + public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { + long startTime = System.currentTimeMillis(); + + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + + + String request_direction = ""; + if (method.isAnnotationPresent(ToOthersInterfaceLog.class)) { + ToOthersInterfaceLog interfaceLog = method.getAnnotation(ToOthersInterfaceLog.class); + request_direction = interfaceLog.value(); + } + String methodName = joinPoint.getSignature().getName(); + Object[] args = joinPoint.getArgs(); + Object url = ""; + Object requesr_param = ""; + if (args.length > 1) { + url = args[0]; + requesr_param = args[1]; + } + + Class targetClass = joinPoint.getTarget().getClass(); + + Object ipPort = ""; + try { + Field requestAdapterField = fieldCache.computeIfAbsent(targetClass, clazz -> { + try { + Field field = clazz.getDeclaredField("REQUEST_ADAPTER"); + ReflectionUtils.makeAccessible(field); + return field; + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + }); + + Object requestAdapterObject = requestAdapterField.get(null); + + Method getUrlMethod = methodCache.computeIfAbsent(requestAdapterObject.getClass(), clazz -> { + try { + Method m = clazz.getDeclaredMethod("getUrl"); + ReflectionUtils.makeAccessible(m); + return m; + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + }); + + ipPort = getUrlMethod.invoke(requestAdapterObject); + } catch (Exception e) { + LuceneLogDto logDto = + LuceneLogDto.builder() + .logType("接口日志") + .request_url(ipPort + String.valueOf(url)) + .request_direction(request_direction) + .request_param(JSON.toJSONString(requesr_param)) + .method(methodName) + .content("开始请求,获取url失败," + e.getMessage()) + .build(); + logService.interfaceExecuteLog(logDto); + } + + LuceneLogDto logDto = + LuceneLogDto.builder() + .logType("接口日志") + .request_url(ipPort + String.valueOf(url)) + .request_direction(request_direction) + .request_param(JSON.toJSONString(requesr_param)) + .method(methodName) + .content("开始请求") + .build(); + logService.interfaceExecuteLog(logDto); + + Object result = joinPoint.proceed(); + + logDto = + LuceneLogDto.builder() + .logType("接口日志") + .request_url(ipPort + String.valueOf(url)) + .request_direction(request_direction) + .request_param(JSON.toJSONString(requesr_param)) + .method(methodName) + .response_param(JSON.toJSONString(result)) + .executeTime(System.currentTimeMillis() - startTime) + .content("响应请求") + .build(); + logService.interfaceExecuteLog(logDto); + return result; + } +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/ToOthersInterfaceLog.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/ToOthersInterfaceLog.java new file mode 100644 index 0000000..76b74b3 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/log/ToOthersInterfaceLog.java @@ -0,0 +1,12 @@ +package org.nl.acs.ext.log; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ToOthersInterfaceLog { + String value() default ""; +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/IpUtil.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/IpUtil.java new file mode 100644 index 0000000..6c969f0 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/IpUtil.java @@ -0,0 +1,35 @@ +package org.nl.acs.ext.wms; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/6/25 + */ +public class IpUtil { + + public static final String LOCAL_IP = localIP(); + + public static String localIP() { + try { + Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + NetworkInterface networkInterface = networkInterfaces.nextElement(); + Enumeration inetAddresses = networkInterface.getInetAddresses(); + while (inetAddresses.hasMoreElements()) { + InetAddress inetAddress = inetAddresses.nextElement(); + if (!inetAddress.isLoopbackAddress() && inetAddress instanceof java.net.Inet4Address) { + return inetAddress.getHostAddress(); + } + } + } + } catch (SocketException e) { + e.printStackTrace(); + } + return ""; + } +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/LmsHttpUtil.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/LmsHttpUtil.java new file mode 100644 index 0000000..d40b2da --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/LmsHttpUtil.java @@ -0,0 +1,133 @@ +package org.nl.acs.ext.wms; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpRequest; +import com.alibaba.fastjson.JSON; +import org.nl.acs.config.AcsConfig; +import org.nl.acs.ext.RequestAdapter; +import org.nl.acs.ext.ResponseAdapter; +import org.nl.acs.ext.UnifiedResponse; +import org.nl.acs.ext.log.ToOthersInterfaceLog; +import org.nl.modules.system.service.ParamService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/4/22 + */ +@Component +public class LmsHttpUtil { + + private static final RequestAdapter REQUEST_ADAPTER = new LmsRequestAdapter(); + private static final ResponseAdapter RESPONSE_ADAPTER = new LmsResponseAdapter(); + + @Autowired + private ParamService paramService; + + @ToOthersInterfaceLog("ACS->LMS") + public UnifiedResponse sendPostRequest(String path, W requestParam, Class type) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.HAS_WMS).getValue(), "1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .post(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(5000) + .body(JSON.toJSONString(requestParam)) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, type); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + + @ToOthersInterfaceLog("ACS->LMS") + public UnifiedResponse sendPostRequest(String path, W requestParam) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.HAS_WMS).getValue(),"1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .post(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(5000) + .body(JSON.toJSONString(requestParam)) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, null); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + + @ToOthersInterfaceLog("ACS->LMS") + public UnifiedResponse sendPostRequest(String path, Class type) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.HAS_WMS).getValue(), "1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .post(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(5000) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, type); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + + @ToOthersInterfaceLog("ACS->LMS") + public UnifiedResponse sendPostRequest(String path) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.HAS_WMS).getValue(), "1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .post(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(5000) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, null); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + + @ToOthersInterfaceLog("ACS->LMS") + public UnifiedResponse sendGetRequest(String path, Class type) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.HAS_WMS).getValue(), "1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .get(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(5000) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, type); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + + @ToOthersInterfaceLog("ACS->LMS") + public UnifiedResponse sendGetRequest(String path) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.HAS_WMS).getValue(), "1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .get(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(5000) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, null); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/LmsRequestAdapter.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/LmsRequestAdapter.java new file mode 100644 index 0000000..eda2aa8 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/LmsRequestAdapter.java @@ -0,0 +1,20 @@ +package org.nl.acs.ext.wms; + + +import org.nl.acs.config.AcsConfig; +import org.nl.acs.ext.RequestAdapter; +import org.nl.modules.system.service.ParamService; +import org.nl.modules.wql.util.SpringContextHolder; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/4/22 + */ +public class LmsRequestAdapter implements RequestAdapter { + @Override + public String getUrl() { + ParamService paramService = SpringContextHolder.getBean(ParamService.class); + return paramService.findByCode(AcsConfig.WMS_URL).getValue(); + } +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/LmsResponseAdapter.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/LmsResponseAdapter.java new file mode 100644 index 0000000..5ddb825 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/LmsResponseAdapter.java @@ -0,0 +1,31 @@ +package org.nl.acs.ext.wms; + +import com.alibaba.fastjson.JSONObject; +import org.nl.acs.ext.ResponseAdapter; +import org.nl.acs.ext.UnifiedResponse; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/4/22 + */ +public class LmsResponseAdapter implements ResponseAdapter { + + @Override + public UnifiedResponse adapt(String responseBody, Class type) { + JSONObject jsonResponse = JSONObject.parseObject(responseBody); + boolean isSuccess = jsonResponse.getInteger("code") == 200; + String message = jsonResponse.getString("message"); + if (type != null) { + if (type.isArray()) { + T data = JSONObject.toJavaObject(jsonResponse.getJSONArray("content"), type); + return new UnifiedResponse<>(isSuccess, message, data); + } else { + T data = JSONObject.toJavaObject(jsonResponse.getJSONObject("data"), type); + return new UnifiedResponse<>(isSuccess, message, data); + } + } + return new UnifiedResponse<>(isSuccess, message); + } + +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/rest/WmsToAcsController.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/rest/WmsToAcsController.java index 596780c..c5af279 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/rest/WmsToAcsController.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/rest/WmsToAcsController.java @@ -8,8 +8,13 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.nl.acs.ext.log.OthersToInterfaceLog; import org.nl.acs.ext.wms.service.WmsToAcsService; +import org.nl.acs.monitor.DeviceStageMonitor; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceAppService; import org.nl.modules.logging.annotation.Log; +import org.nl.modules.wql.util.SpringContextHolder; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; @@ -31,16 +36,30 @@ public class WmsToAcsController { private final WmsToAcsService wmstoacsService; @PostMapping("/task") - @Log("接收WMS任务") - @ApiOperation("接收WMS任务") + @OthersToInterfaceLog("LMS->ACS") public ResponseEntity createFromWms(@RequestBody JSONObject whereJson) { return new ResponseEntity<>(wmstoacsService.createFromWms(whereJson), HttpStatus.OK); } @PostMapping("/cancelTask") - @Log("WMS取消任务") - @ApiOperation("WMS取消任务") + @OthersToInterfaceLog("LMS->ACS") public ResponseEntity cancelFromWms(@RequestBody String whereJson) throws Exception { return new ResponseEntity<>(wmstoacsService.cancelFromWms(whereJson), HttpStatus.OK); } + + @PostMapping("/获取AGV和RGV数据") + @OthersToInterfaceLog("LMS->ACS") + public ResponseEntity getAGVAndRGVInfo() { + return new ResponseEntity<>(wmstoacsService.getAGVAndRGVInfo(), HttpStatus.OK); + } + + @PostMapping("/test") + public ResponseEntity test() throws Exception { + DeviceAppService deviceAppService = SpringContextHolder.getBean(DeviceAppService.class); + Device device = deviceAppService.findDeviceByCode("AMB-01"); + if (device.getDeviceDriver() instanceof DeviceStageMonitor) { + DeviceStageMonitor monitorService = (DeviceStageMonitor) device.getDeviceDriver(); + } + return new ResponseEntity<>(HttpStatus.OK); + } } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java index 965066e..6ad94ad 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java @@ -1,5 +1,6 @@ package org.nl.acs.ext.wms.service; +import org.nl.acs.ext.UnifiedResponse; import org.nl.acs.ext.wms.data.BaseRequest; public interface AcsToWmsService { @@ -9,4 +10,8 @@ public interface AcsToWmsService { */ public String applyTask(BaseRequest request); + UnifiedResponse apply(BaseRequest requestParam); + + UnifiedResponse apply(BaseRequest requestParam, Class type); + } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/WmsToAcsService.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/WmsToAcsService.java index cae6591..fb766cb 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/WmsToAcsService.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/WmsToAcsService.java @@ -24,4 +24,5 @@ public interface WmsToAcsService { */ Map cancelFromWms(String jsonObject) throws Exception; + JSONObject getAGVAndRGVInfo(); } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java index a28fa5c..b10945f 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java @@ -3,6 +3,9 @@ package org.nl.acs.ext.wms.service.impl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.nl.acs.device.address.service.AddressService; +import org.nl.acs.device.address.service.dto.AddressDto; +import org.nl.acs.ext.UnifiedResponse; +import org.nl.acs.ext.wms.LmsHttpUtil; import org.nl.acs.ext.wms.LmsUtil; import org.nl.acs.ext.wms.data.BaseRequest; import org.nl.acs.ext.wms.service.AcsToWmsService; @@ -18,10 +21,25 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { @Autowired private AddressService addressService; + @Autowired + private LmsHttpUtil lmsHttpUtil; + @Override public String applyTask(BaseRequest requestParam) { String api = addressService.findByCode("lnshApplyTaskToWms").getMethods_url(); String result = LmsUtil.notifyAcs(api, requestParam); return result; } + + @Override + public UnifiedResponse apply(BaseRequest requestParam) { + AddressDto addressDto = addressService.findByCode("lnshApplyTaskToWms"); + return lmsHttpUtil.sendPostRequest(addressDto.getMethods_url(), requestParam); + } + + @Override + public UnifiedResponse apply(BaseRequest requestParam, Class type) { + AddressDto addressDto = addressService.findByCode("lnshApplyTaskToWms"); + return lmsHttpUtil.sendPostRequest(addressDto.getMethods_url(), requestParam, type); + } } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java index 240d922..716ccdd 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java @@ -6,21 +6,28 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.nl.acs.agv.AgvUtil; import org.nl.acs.config.AcsConfig; import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; import org.nl.acs.ext.wms.data.wmsToAcsData.createTask.CreateTaskRequest; import org.nl.acs.ext.wms.data.wmsToAcsData.createTask.CreateTaskResponse; import org.nl.acs.ext.wms.service.WmsToAcsService; import org.nl.acs.instruction.service.InstructionService; import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.monitor.DeviceStageMonitor; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceAppService; +import org.nl.acs.opc.DeviceType; 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.lucene.service.LuceneExecuteLogService; import org.nl.modules.lucene.service.dto.LuceneLogDto; +import org.nl.modules.quartz.task.DeviceStatusMonitor; import org.nl.modules.system.service.ParamService; import org.nl.modules.system.service.impl.ParamServiceImpl; import org.nl.modules.wql.core.bean.WQLObject; @@ -30,6 +37,7 @@ import org.slf4j.MDC; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -42,6 +50,7 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { private final TaskService TaskService; private final DeviceService DeviceService; private final RouteLineService RouteLineService; + private final DeviceAppService deviceAppService; private String log_file_type = "log_file_type"; private String log_type = "WMS下发ACS"; @@ -241,13 +250,13 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { resp.setMessage("请求成功"); log.info("createFromWms - 返回参数 {}", JSON.toJSON(resp)); - LuceneLogDto logDto = LuceneLogDto.builder() - .requestparam(JSON.toJSON(resp).toString()) - .responseparam(JSON.toJSON(resp).toString()) - .status_code(String.valueOf(resp.getCode())) - .method(tasks.getRequest_medthod_code()) - .build(); - lucene.interfaceExecuteLog(logDto); +// LuceneLogDto logDto = LuceneLogDto.builder() +// .requestparam(JSON.toJSON(resp).toString()) +// .responseparam(JSON.toJSON(resp).toString()) +// .status_code(String.valueOf(resp.getCode())) +// .method(tasks.getRequest_medthod_code()) +// .build(); +// lucene.interfaceExecuteLog(logDto); return (JSONObject) JSON.toJSON(resp); } finally { MDC.remove(log_file_type); @@ -301,4 +310,29 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { MDC.remove(log_file_type); } } + + @SneakyThrows + @Override + public JSONObject getAGVAndRGVInfo() { + JSONObject resp = new JSONObject(); + List agvs = deviceAppService.findDevice(DeviceType.agv); + List agvInfos = new ArrayList<>(); + for (Device agv : agvs) { + if (agv != null && agv.getDeviceDriver() instanceof DeviceStatusMonitor) { + DeviceStageMonitor deviceStageMonitor = (DeviceStageMonitor) agv.getDeviceDriver(); + agvInfos.add(deviceStageMonitor.getDeviceStatusName()); + } + } + resp.put("agv", agvInfos); + List rgvs = deviceAppService.findDevice(DeviceType.rgv); + List rgvInfos = new ArrayList<>(); + for (Device rgv : rgvs) { + if (rgv != null && rgv.getDeviceDriver() instanceof DeviceStatusMonitor) { + DeviceStageMonitor deviceStageMonitor = (DeviceStageMonitor) rgv.getDeviceDriver(); + rgvInfos.add(deviceStageMonitor.getDeviceStatusName()); + } + } + resp.put("rgv", rgvInfos); + return resp; + } } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/xg/XgHttpUtil.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/xg/XgHttpUtil.java new file mode 100644 index 0000000..9ecd29b --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/xg/XgHttpUtil.java @@ -0,0 +1,135 @@ +package org.nl.acs.ext.xg; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpRequest; +import com.alibaba.fastjson.JSON; +import org.nl.acs.config.AcsConfig; +import org.nl.acs.ext.RequestAdapter; +import org.nl.acs.ext.ResponseAdapter; +import org.nl.acs.ext.UnifiedResponse; +import org.nl.acs.ext.log.ToOthersInterfaceLog; +import org.nl.modules.system.service.ParamService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/4/22 + */ +@Component +public class XgHttpUtil { + + private static final RequestAdapter REQUEST_ADAPTER = new XgRequestAdapter(); + private static final ResponseAdapter RESPONSE_ADAPTER = new XgResponseAdapter(); + + @Autowired + private ParamService paramService; + + @ToOthersInterfaceLog("ACS->AGV") + public UnifiedResponse sendPostRequest(String path, W requestParam, Class type) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .post(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(10000) + .body(JSON.toJSONString(requestParam)) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, type); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + + @ToOthersInterfaceLog("ACS->AGV") + public UnifiedResponse sendPostRequest(String path, W requestParam) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .post(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(10000) + .body(JSON.toJSONString(requestParam)) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, null); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + + @ToOthersInterfaceLog("ACS->AGV") + public UnifiedResponse sendPostRequest(String path, Class type) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .post(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(10000) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, type); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + + + @ToOthersInterfaceLog("ACS->AGV") + public UnifiedResponse sendPostRequest(String path) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .post(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(10000) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, null); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + + + @ToOthersInterfaceLog("ACS->AGV") + public UnifiedResponse sendGetRequest(String path, Class type) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(),"1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .get(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(10000) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, type); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + + @ToOthersInterfaceLog("ACS->AGV") + public UnifiedResponse sendGetRequest(String path) { + if (!StrUtil.equals(paramService.findByCode(AcsConfig.FORK_AGV).getValue(), "1")) { + return new UnifiedResponse<>(false, "未开启连接该系统!"); + } + try { + String body = HttpRequest + .get(REQUEST_ADAPTER.getUrl() + path) + .setConnectionTimeout(10000) + .execute() + .body(); + return RESPONSE_ADAPTER.adapt(body, null); + } catch (Exception e) { + return new UnifiedResponse<>(false, e.getMessage()); + } + } + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/xg/XgRequestAdapter.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/xg/XgRequestAdapter.java new file mode 100644 index 0000000..09dc4b2 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/xg/XgRequestAdapter.java @@ -0,0 +1,21 @@ +package org.nl.acs.ext.xg; + +import org.nl.acs.config.AcsConfig; +import org.nl.acs.ext.RequestAdapter; +import org.nl.modules.system.service.ParamService; +import org.nl.modules.wql.util.SpringContextHolder; + + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/4/22 + */ +public class XgRequestAdapter implements RequestAdapter { + @Override + public String getUrl() { + ParamService paramService = SpringContextHolder.getBean(ParamService.class); + return paramService.findByCode(AcsConfig.AGV_URL).getValue(); + } + +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/xg/XgResponseAdapter.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/xg/XgResponseAdapter.java new file mode 100644 index 0000000..f0aa34f --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/xg/XgResponseAdapter.java @@ -0,0 +1,44 @@ +package org.nl.acs.ext.xg; + + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.nl.acs.ext.ResponseAdapter; +import org.nl.acs.ext.UnifiedResponse; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/4/22 + */ +public class XgResponseAdapter implements ResponseAdapter { + + @Override + public UnifiedResponse adapt(String responseBody, Class type) { + responseBody = responseBody.trim(); + if (responseBody.startsWith("{") && responseBody.endsWith("}")) { + JSONObject resp = JSON.parseObject(responseBody); + String message = resp.containsKey("msg") ? resp.getString("msg") : ""; + if (resp.containsKey("code") && resp.getInteger("code") != 0) { + return new UnifiedResponse<>(false, message); + } else { + if (type != null) { + T data = JSONObject.toJavaObject(resp, type); + return new UnifiedResponse<>(true, message, data); + } + return new UnifiedResponse<>(true, message, (T) resp); + } + } else if (responseBody.startsWith("[") && responseBody.endsWith("]")) { + JSONArray resp = JSON.parseArray(responseBody); + if (type != null) { + T data = JSONObject.toJavaObject(resp, type); + return new UnifiedResponse<>(true, "success", data); + } else { + return new UnifiedResponse<>(true, "success", (T) resp); + } + } else { + return new UnifiedResponse<>(false, "failed,响应数据为空!"); + } + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/InstructionService.java b/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/InstructionService.java index cc48d9a..1835a67 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/InstructionService.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/InstructionService.java @@ -198,4 +198,7 @@ public interface InstructionService { void sendToAGV(String id); + Integer findTodayTaskNumByAgvCar(String currentDeviceCode); + + Integer findMonthTaskNumByAgvCar(String currentDeviceCode); } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/impl/InstructionServiceImpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/impl/InstructionServiceImpl.java index c7b9672..dee2cea 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/impl/InstructionServiceImpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/impl/InstructionServiceImpl.java @@ -19,6 +19,7 @@ import org.nl.acs.config.AcsConfig; import org.nl.acs.device.service.DeviceService; import org.nl.acs.device.service.impl.DeviceServiceImpl; import org.nl.acs.device_driver.lamp_three_color.LampThreecolorDeviceDriver; +import org.nl.acs.ext.UnifiedResponse; import org.nl.acs.instruction.service.InstructionService; import org.nl.acs.instruction.service.dto.Instruction; import org.nl.acs.opc.Device; @@ -271,10 +272,6 @@ public class InstructionServiceImpl implements InstructionService, ApplicationAu dto.setNext_parent_code(task.getNext_parent_code()); - WQLObject wo = WQLObject.getWQLObject("acs_instruction"); - JSONObject json = (JSONObject) JSONObject.toJSON(dto); - wo.insert(json); - try { // != 0 为agv任务 if (!StrUtil.equals(type, "0")) { @@ -295,8 +292,8 @@ public class InstructionServiceImpl implements InstructionService, ApplicationAu if (StrUtil.equals(task.getRequest_again_success(), "1")) { XianGongAgvServiceImpl xianGongAgv = SpringContextHolder.getBean(XianGongAgvServiceImpl.class); //追加订单 - HttpResponse result = xianGongAgv.addOrderSequences(dto); - if (ObjectUtils.isEmpty(result) || result.getStatus() != 200) { + UnifiedResponse response = xianGongAgv.addOrderSequences(dto); + if (!response.isSuccess()) { dto.setSend_status("2"); } else { dto.setSend_status("1"); @@ -304,8 +301,8 @@ public class InstructionServiceImpl implements InstructionService, ApplicationAu } else { XianGongAgvServiceImpl xianGongAgv = SpringContextHolder.getBean(XianGongAgvServiceImpl.class); //创建订单序列 - HttpResponse result = xianGongAgv.sendOrderSequencesToXZ(dto); - if (ObjectUtils.isEmpty(result) || result.getStatus() != 200) { + UnifiedResponse response = xianGongAgv.sendOrderSequencesToXZ(dto); + if (!response.isSuccess()) { dto.setSend_status("2"); } else { dto.setSend_status("1"); @@ -317,7 +314,9 @@ public class InstructionServiceImpl implements InstructionService, ApplicationAu dto.setSend_status("2"); e.printStackTrace(); } - + WQLObject wo = WQLObject.getWQLObject("acs_instruction"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + wo.insert(json); this.instructions.add(dto); } @@ -745,8 +744,8 @@ public class InstructionServiceImpl implements InstructionService, ApplicationAu if (StrUtil.equals(task.getRequest_again_success(), "1")) { XianGongAgvServiceImpl xianGongAgv = SpringContextHolder.getBean(XianGongAgvServiceImpl.class); //追加订单 - HttpResponse result = xianGongAgv.addOrderSequences(dto); - if (ObjectUtils.isEmpty(result) || result.getStatus() != 200) { + UnifiedResponse response = xianGongAgv.addOrderSequences(dto); + if (!response.isSuccess()) { dto.setSend_status("2"); } else { dto.setSend_status("1"); @@ -754,8 +753,8 @@ public class InstructionServiceImpl implements InstructionService, ApplicationAu } else { XianGongAgvServiceImpl xianGongAgv = SpringContextHolder.getBean(XianGongAgvServiceImpl.class); //创建订单序列 - HttpResponse result = xianGongAgv.sendOrderSequencesToXZ(dto); - if (ObjectUtils.isEmpty(result) || result.getStatus() != 200) { + UnifiedResponse response = xianGongAgv.sendOrderSequencesToXZ(dto); + if (!response.isSuccess()) { dto.setSend_status("2"); } else { dto.setSend_status("1"); @@ -770,5 +769,23 @@ public class InstructionServiceImpl implements InstructionService, ApplicationAu this.update(dto); } + @Override + public Integer findTodayTaskNumByAgvCar(String currentDeviceCode) { + Map map = new HashMap<>(); + map.put("flag", "3"); + map.put("carno", currentDeviceCode); + JSONObject jsonObject = WQL.getWO("QINST_QUERY").addParamMap(map).process().uniqueResult(0); + return jsonObject.getInteger("total_count"); + } + + @Override + public Integer findMonthTaskNumByAgvCar(String currentDeviceCode) { + Map map = new HashMap<>(); + map.put("flag", "4"); + map.put("carno", currentDeviceCode); + JSONObject jsonObject = WQL.getWO("QINST_QUERY").addParamMap(map).process().uniqueResult(0); + return jsonObject.getInteger("total_count"); + } + } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/wql/QINST_QUERY.wql b/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/wql/QINST_QUERY.wql index 170478f..aa133a8 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/wql/QINST_QUERY.wql +++ b/acs/nladmin-system/src/main/java/org/nl/acs/instruction/service/wql/QINST_QUERY.wql @@ -17,10 +17,10 @@ 输入.code TYPEAS s_string 输入.vehicle_code TYPEAS s_string 输入.material_type TYPEAS s_string - 输入.status TYPEAS s_string - 输入.point_code TYPEAS s_string - 输入.point_code TYPEAS s_string - 输入.create_time TYPEAS time + 输入.status TYPEAS s_string + 输入.point_code TYPEAS s_string + 输入.carno TYPEAS s_string + 输入.create_time TYPEAS time 输入.end_time TYPEAS time @@ -124,3 +124,27 @@ ENDSELECT ENDPAGEQUERY ENDIF + + IF 输入.flag = "3" + QUERY + SELECT COUNT(*) AS total_count + FROM acs_instruction inst + WHERE is_delete = 0 AND DATE(inst.create_time) = CURDATE() + OPTION 输入.carno <> "" + inst.carno = 输入.carno + ENDOPTION + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "4" + QUERY + SELECT COUNT(*) AS total_count + FROM acs_instruction inst + WHERE is_delete = '0' AND inst.create_time >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH) + OPTION 输入.carno <> "" + inst.carno = 输入.carno + ENDOPTION + ENDSELECT + ENDQUERY + ENDIF diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceExecuteAutoRun.java b/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceExecuteAutoRun.java index 907788d..edf2fa1 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceExecuteAutoRun.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceExecuteAutoRun.java @@ -77,7 +77,7 @@ public class DeviceExecuteAutoRun extends AbstractAutoRunnable { for (int i = 0; !OpcStartTag.is_run; ++i) { log.info("设备执行线程等待opc同步线程..."); Thread.sleep(1000L); - if (i > 60) { + if (i > 20) { log.info("设备执行线程放弃等待opc同步线程..."); break; } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceOpcProtocolRunable.java b/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceOpcProtocolRunable.java index e4503f7..a42560d 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceOpcProtocolRunable.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceOpcProtocolRunable.java @@ -77,9 +77,9 @@ public class DeviceOpcProtocolRunable implements Runnable, DataCallback, ServerC @Override public void run() { if (OpcConfig.opc_item_read_using_callback) { - this.runNew(); + // this.runNew(); } else { - this.runOld(); + // this.runOld(); } } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceOpcSynchronizeAutoRun.java b/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceOpcSynchronizeAutoRun.java index 1817f8e..fc39f06 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceOpcSynchronizeAutoRun.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceOpcSynchronizeAutoRun.java @@ -47,40 +47,40 @@ public class DeviceOpcSynchronizeAutoRun extends AbstractAutoRunnable { @Override public void autoRun() throws Exception { - { - isRun = true; - - Map servers = this.opcServerManageService.queryAllServerMap(); - Map>> pros; - do{ - Thread.sleep(1000L); - pros = this.deviceAppService.findAllFormatProtocolFromDriver(); - }while (ObjectUtil.isEmpty(pros)); - Set keys = pros.keySet(); - Iterator var4 = keys.iterator(); - //代码执行一次 - while (var4.hasNext()) { - String key = (String) var4.next(); - List> list = (List) pros.get(key); - OpcServerManageDto opcServer = (OpcServerManageDto) servers.get(key); - Iterator var8 = list.iterator(); - while (var8.hasNext()) { - List groupProtols = (List) var8.next(); - DeviceOpcProtocolRunable runable = new DeviceOpcProtocolRunable(); - runable.setProtocols(groupProtols); - runable.setOpcServer(opcServer); - this.executorService.submit(runable); - } - } - - // 同步无光电设备信号 - //Map>> pros1 = this.deviceAppService.findAllFormatProtocolFromDriver(); - //List opcDrivers = this.deviceAppService.findDeviceDriver(DeviceDriver.class); - - while (true) { - Thread.sleep(3000L); - } - } +// { +// isRun = true; +// +// Map servers = this.opcServerManageService.queryAllServerMap(); +// Map>> pros; +// do{ +// Thread.sleep(1000L); +// pros = this.deviceAppService.findAllFormatProtocolFromDriver(); +// }while (ObjectUtil.isEmpty(pros)); +// Set keys = pros.keySet(); +// Iterator var4 = keys.iterator(); +// //代码执行一次 +// while (var4.hasNext()) { +// String key = (String) var4.next(); +// List> list = (List) pros.get(key); +// OpcServerManageDto opcServer = (OpcServerManageDto) servers.get(key); +// Iterator var8 = list.iterator(); +// while (var8.hasNext()) { +// List groupProtols = (List) var8.next(); +// DeviceOpcProtocolRunable runable = new DeviceOpcProtocolRunable(); +// runable.setProtocols(groupProtols); +// runable.setOpcServer(opcServer); +// this.executorService.submit(runable); +// } +// } +// +// // 同步无光电设备信号 +// //Map>> pros1 = this.deviceAppService.findAllFormatProtocolFromDriver(); +// //List opcDrivers = this.deviceAppService.findDeviceDriver(DeviceDriver.class); +// +// while (true) { +// Thread.sleep(3000L); +// } +// } } @Override diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java index 6fc8308..34969a2 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java @@ -184,7 +184,7 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { int totalElements = (Integer) jsonObject.get("totalElements"); JSONArray arr = new JSONArray(); for (int i = 0; i < array.size(); i++) { - JSONObject object = arr.getJSONObject(i); + JSONObject object = array.getJSONObject(i); object.put("hasChildren", true); arr.add(object); } @@ -686,7 +686,7 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { request.setTask_status(dto.getTask_status()); request.setRequest_medthod_code(RequestMethodEnum.feedback_task_status.getCode()); request.setRequest_medthod_name(RequestMethodEnum.feedback_task_status.getName()); - acstowmsService.applyTask(request); + acstowmsService.apply(request); } } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/udw/TagConfig.java b/acs/nladmin-system/src/main/java/org/nl/acs/udw/TagConfig.java new file mode 100644 index 0000000..3b86754 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/udw/TagConfig.java @@ -0,0 +1,15 @@ +package org.nl.acs.udw; + +/** + * @author 20220102CG\noblelift + */ +public class TagConfig { + + /** + * 历史记录最大数量 + */ + public static int max_history_length = 10; + + public TagConfig() { + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/TagDataAccessor.java b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/TagDataAccessor.java new file mode 100644 index 0000000..fd35cb7 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/TagDataAccessor.java @@ -0,0 +1,20 @@ +package org.nl.acs.udw.mqttUdw; + +import java.util.List; + +/** + * @author onepiece + */ +public interface TagDataAccessor { + List getAllKey(); + + Object getValue(String key); + + Boolean getQ(String key); + + void setValue(String key, Object value); + + void setValue(String key, Object value, Boolean q); + + void setValueWithPersistence(String key, Object value); +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/TagProcessorService.java b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/TagProcessorService.java new file mode 100644 index 0000000..d9a6d6c --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/TagProcessorService.java @@ -0,0 +1,40 @@ +package org.nl.acs.udw.mqttUdw; + +import org.nl.acs.udw.mqttUdw.service.TagData; +import org.nl.acs.udw.mqttUdw.service.TagUnit; + +import java.util.List; + +/** + * @author onepiece + */ +public interface TagProcessorService { + /** + * 获取所有的key + * + * @return + */ + List getAllUnifiedKey(); + + /** + * 根据key获取数据单元 + * + * @param key + * @return + */ + TagUnit getTagUnit(String key); + + TagData getTagData(String var1, String var2); + + Object getValue(String var1, String var2); + + void setValue(String var1, String var2, Object var3); + + void setVaule(String unified_key, String key,Object value, Boolean q); + + List getAllDataKey(String var1); + + void setValueWithPersistence(String var1, String var2, Object var3); + + Boolean getQ(String unified_key, String key); +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/factory/TagProcessorFactory.java b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/factory/TagProcessorFactory.java new file mode 100644 index 0000000..175d3c5 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/factory/TagProcessorFactory.java @@ -0,0 +1,17 @@ +package org.nl.acs.udw.mqttUdw.factory; + +import org.nl.acs.udw.mqttUdw.TagProcessorService; +import org.nl.acs.udw.mqttUdw.service.TagProcessorImpl; + +/** + * @author onepiece + */ +public class TagProcessorFactory { + + private static final TagProcessorService TAGS_PROCESSOR = new TagProcessorImpl(); + + + public static TagProcessorService getTagsProcessor() { + return TAGS_PROCESSOR; + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/factory/TagsDataAccessorFactory.java b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/factory/TagsDataAccessorFactory.java new file mode 100644 index 0000000..24f95eb --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/factory/TagsDataAccessorFactory.java @@ -0,0 +1,18 @@ +package org.nl.acs.udw.mqttUdw.factory; + +import org.nl.acs.udw.mqttUdw.TagDataAccessor; +import org.nl.acs.udw.mqttUdw.service.TagDataAccessorImpl; + +/** + * @author onepiece + */ +public class TagsDataAccessorFactory { + + private static final TagDataAccessorImpl TAGS_ACCESSOR = new TagDataAccessorImpl(); + + public static TagDataAccessor getTagsAccessor(String unified_key) { + TAGS_ACCESSOR.setUnifiedKey(unified_key); + TAGS_ACCESSOR.setItemsProcess(TagProcessorFactory.getTagsProcessor()); + return TAGS_ACCESSOR; + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagData.java b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagData.java new file mode 100644 index 0000000..b8105f9 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagData.java @@ -0,0 +1,47 @@ +package org.nl.acs.udw.mqttUdw.service; + +import lombok.Data; + +import java.util.Date; + +/** + * @author onepiece + */ +@Data +public class TagData { + private Object value; + private Boolean q; + private Date last_modify_date; + + public TagData() { + this.last_modify_date = new Date(); + } + + + public TagData(Object value) { + this.value = value; + this.last_modify_date = new Date(); + } + + public TagData(Object value, Boolean q) { + this.value = value; + this.q = q; + this.last_modify_date = new Date(); + } + + public void changeQ(Boolean q) { + this.q = q; + this.last_modify_date = new Date(); + } + + public void changeValue(Object value) { + this.value = value; + this.last_modify_date = new Date(); + } + + public void changeValue(Object value, Boolean q) { + this.value = value; + this.q = q; + this.last_modify_date = new Date(); + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagDataAccessorImpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagDataAccessorImpl.java new file mode 100644 index 0000000..490e96e --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagDataAccessorImpl.java @@ -0,0 +1,54 @@ +package org.nl.acs.udw.mqttUdw.service; + +import org.nl.acs.udw.mqttUdw.TagDataAccessor; +import org.nl.acs.udw.mqttUdw.TagProcessorService; + +import java.util.List; + +/** + * @author onepiece + */ +public class TagDataAccessorImpl implements TagDataAccessor { + + private String unified_key; + private TagProcessorService tagProcess; + + + public void setUnifiedKey(String unified_key) { + this.unified_key = unified_key; + } + + public void setItemsProcess(TagProcessorService tagProcess) { + this.tagProcess = tagProcess; + } + + @Override + public List getAllKey() { + return this.tagProcess.getAllDataKey(this.unified_key); + } + + @Override + public Object getValue(String key) { + return this.tagProcess.getValue(this.unified_key, key); + } + + @Override + public Boolean getQ(String key) { + return this.tagProcess.getQ(this.unified_key, key); + } + + @Override + public void setValue(String key, Object value) { + this.tagProcess.setValue(this.unified_key, key, value); + } + + @Override + public void setValue(String key, Object value, Boolean q) { + this.tagProcess.setVaule(this.unified_key, key, value, q); + } + + @Override + public void setValueWithPersistence(String key, Object value) { + this.tagProcess.setValueWithPersistence(this.unified_key, key, value); + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagProcessorImpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagProcessorImpl.java new file mode 100644 index 0000000..05b9cae --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagProcessorImpl.java @@ -0,0 +1,165 @@ +package org.nl.acs.udw.mqttUdw.service; + +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.udw.TagConfig; +import org.nl.acs.udw.mqttUdw.TagProcessorService; +import org.nl.modules.common.exception.BadRequestException; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author onepiece + */ +@Slf4j +public class TagProcessorImpl implements TagProcessorService { + private Map factory = new ConcurrentHashMap<>(); + + public TagProcessorImpl() { + } + + + @Override + public List getAllUnifiedKey() { + return new ArrayList(this.factory.keySet()); + } + + @Override + public TagUnit getTagUnit(String unified_key) { + TagUnit tagUnit = this.factory.get(unified_key); + return tagUnit == null ? null : tagUnit; + } + + @Override + public List getAllDataKey(String unified_key) { + TagUnit tagUnit = (TagUnit) this.factory.get(unified_key); + if (tagUnit == null) { + return new ArrayList(); + } else { + Map storage = tagUnit.getStorage(); + return new ArrayList(storage.keySet()); + } + } + + @Override + public void setValueWithPersistence(String unified_key, String key, Object value) { + this.setValue(unified_key, key, value, true, true); + } + + @Override + public TagData getTagData(String unified_key, String key) { + TagUnit tagUnit = this.getTagUnit(unified_key); + if (tagUnit == null) { + return null; + } else { + Map storage = tagUnit.getStorage(); + return (TagData) storage.get(key); + } + } + + @Override + public Object getValue(String unified_key, String key) { + TagData tagData = this.getTagData(unified_key, key); + return tagData == null ? null : tagData.getValue(); + } + + @Override + public Boolean getQ(String unified_key, String key) { + TagData tagData = this.getTagData(unified_key, key); + return tagData == null ? null : tagData.getQ(); + } + + @Override + public void setValue(String unified_key, String key, Object value) { + this.setValue(unified_key, key, value, false, true); + } + + @Override + public void setVaule(String unified_key, String key, Object value, Boolean q) { + this.setVaule(unified_key, key, value, q); + } + + public synchronized void setValue(String unified_key, String key, Object value, Boolean q) { + if (unified_key != null && key != null) { + if (!this.factory.containsKey(unified_key)) { + this.factory.put(unified_key, new TagUnit(unified_key)); + } + TagUnit tagUnit = this.factory.get(unified_key); + Map storage = tagUnit.getStorage(); + if (!storage.containsKey(key)) { + storage.put(key, new TagData()); + } + TagData tagData = storage.get(key); + if (!ObjectUtil.equals(tagData.getValue(), value) || !ObjectUtil.equals(tagData.getQ(), q)) { + Map> history = tagUnit.getHistory(); + List historyTagDatas = history.get(key); + if (historyTagDatas == null) { + history.put(key, new ArrayList()); + } + TagData historyData = new TagData(); + historyData.setLast_modify_date(tagData.getLast_modify_date()); + historyData.setValue(tagData.getValue()); + historyData.setQ(q); + while ((history.get(key)).size() > TagConfig.max_history_length) { + history.get(key).remove(TagConfig.max_history_length); + } + history.get(key).add(0, historyData); + Object oldValue = tagData.getValue(); + tagData.changeValue(value, q); + //log.trace("统一数据源中: unit: {}, key: {}, 值: {} 更改为 {}。", new Object[]{unified_key, key, oldValue, value}); + } + } else { + log.error("统一数据源失败,{},{},{},{}", unified_key, key, value, q); + } + } + + + public synchronized void setValue(String unified_key, String key, Object value, boolean save, boolean is_log) { + if (unified_key == null) { + throw new BadRequestException(""); + //throw new BusinessException(SystemMessage.cant_be_empty, new Object[]{"unified_key"}); + } else if (key == null) { + throw new BadRequestException(""); + //throw new BusinessException(SystemMessage.cant_be_empty, new Object[]{"key"}); + } else { + if (!this.factory.containsKey(unified_key)) { + this.factory.put(unified_key, new TagUnit(unified_key)); + } + + TagUnit tagUnit = (TagUnit) this.factory.get(unified_key); + Map storage = tagUnit.getStorage(); + if (!storage.containsKey(key)) { + storage.put(key, new TagData()); + } + + TagData tagData = (TagData) storage.get(key); + if (!ObjectUtil.equals(tagData.getValue(), value)) { + Map> history = tagUnit.getHistory(); + List historyItemDatas = (List) history.get(key); + if (historyItemDatas == null) { + history.put(key, new ArrayList()); + } + + TagData historyData = new TagData(); + historyData.setLast_modify_date(tagData.getLast_modify_date()); + historyData.setValue(tagData.getValue()); + + while (((List) history.get(key)).size() > TagConfig.max_history_length) { + ((List) history.get(key)).remove(TagConfig.max_history_length); + } + + ((List) history.get(key)).add(0, historyData); + Object oldvalue = tagData.getValue(); + tagData.changeValue(value); + if (is_log && key != null && !key.endsWith("heartbeat") && !key.endsWith("distancex") && !key.endsWith("distancey") && !key.endsWith("Xwz") && !key.endsWith("Ywz") && !key.endsWith("Zwz")) { + log.trace("统一数据源中: unit: {}, key: {}, 值: {} 更改为 {}。", new Object[]{unified_key, key, oldvalue, value}); + } + } + + } + } + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagUnit.java b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagUnit.java new file mode 100644 index 0000000..2cbc215 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/udw/mqttUdw/service/TagUnit.java @@ -0,0 +1,22 @@ +package org.nl.acs.udw.mqttUdw.service; + +import lombok.Data; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author onepiece + */ +@Data +public class TagUnit { + private String unifiedKey; + private Map storage = new ConcurrentHashMap<>(); + private Map> history = new ConcurrentHashMap<>(); + + public TagUnit(String unifiedKey) { + this.unifiedKey = unifiedKey; + } + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/MqttConfig.java b/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/MqttConfig.java new file mode 100644 index 0000000..21e1e8c --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/MqttConfig.java @@ -0,0 +1,36 @@ +package org.nl.config.mqtt2; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + + +/* + * @author ZZQ + * @Date 2024/1/31 14:07 + */ +@Configuration +@ConfigurationProperties(prefix = "spring.mqtt") +//@ConditionalOnProperty(name = "spring.mqtt.active", havingValue = "true") +@Data +public class MqttConfig { + + private String username; + + private String password; + + private String url; + + private Boolean cleanSession; + + private String clientId; + + private String[] topics; + + private int[] qoss; + + private int timeout; + + private int keepalive; + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/MqttService.java b/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/MqttService.java new file mode 100644 index 0000000..ead4dba --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/MqttService.java @@ -0,0 +1,355 @@ +package org.nl.config.mqtt2; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.hivemq.client.mqtt.MqttClient; +import com.hivemq.client.mqtt.MqttGlobalPublishFilter; +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.lifecycle.MqttClientReconnector; +import com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient; +import lombok.extern.slf4j.Slf4j; +import org.apache.lucene.util.NamedThreadFactory; +import org.nl.acs.auto.initial.ApplicationAutoInitial; +import org.nl.acs.device.service.OpcService; +import org.nl.acs.device.service.dto.OpcDto; +import org.nl.acs.device_driver.driver.AbstractDeviceDriver; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceAppService; +import org.nl.acs.opc.OpcConfig; +import org.nl.acs.udw.mqttUdw.TagDataAccessor; +import org.nl.acs.udw.mqttUdw.factory.TagsDataAccessorFactory; +import org.nl.modules.lucene.enums.DeviceLogTypeEnum; +import org.nl.modules.lucene.service.LuceneExecuteLogService; +import org.nl.modules.lucene.service.dto.LuceneLogDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.*; +import java.util.stream.Collectors; + +/** + * @author onepiece + */ +@Component +//@ConditionalOnProperty(name = "spring.mqtt.active", havingValue = "true") +//@ConditionalOnBean({LuceneExecuteLogService.class, DeviceAppService.class, RedisTemplate.class}) +@Slf4j +public class MqttService implements ApplicationAutoInitial { + + @Autowired(required = false) + @Qualifier("redisTemplateHash") + private RedisTemplate redisTemplateHash; + @Autowired + private MqttConfig mqttConfig; + @Autowired + private LuceneExecuteLogService logService; + @Autowired + private OpcService opcService; + @Autowired + private DeviceAppService deviceAppService; + + + private Mqtt3AsyncClient mqttClient; + + /** + * 根据topic存储订阅消息 + */ + private final Map> topicMap = new ConcurrentHashMap<>(); + + /** + * 存储设备点位信息 + */ + private static final TagDataAccessor ACCESSOR_VALUE = TagsDataAccessorFactory.getTagsAccessor(OpcConfig.udw_opc_value_key); + + /** + * 发布TOPIC + */ + private static final String PUBLISH_TOPIC = "publishTopic"; + + /** + * 重连延迟时间,单位:毫秒 + */ + private static final long RECONNECT_DELAY = 5000L; + + /** + * 最大重连延迟时间,单位:毫秒 + */ + private static final long MAX_RECONNECT_DELAY = 60000L; + + /** + * 存储Redis数据Key + */ + private static final String KEY = "opc:tags"; + + /** + * 心跳tag名称 + */ + private static final String HEARTBEAT = "heartbeat"; + + /** + * 线程池核心线程数量 + */ + private static final int CORE_POOL_SIZE = 1; + + /** + * 线程池最大线程数量 + */ + private static final int MAX_POOL_SIZE = 10; + + /** + * 非核心线程存活时间 + */ + private static final int KEEP_ALIVE_TIME = 10; + + /** + * 用来存储等待执行任务的阻塞队列的大小 + */ + private static final int WORK_QUEUE_SIZE = 100; + + /** + * 队列 + */ + private static final Queue MSG_QUEUE = new LinkedBlockingQueue<>(); + + /** + * 线程工厂 + */ + private final ThreadFactory threadFactory = new NamedThreadFactory("MqttThreadFactory"); + + /** + * 线程池 + */ + private final ThreadPoolExecutor threadPool = new ThreadPoolExecutor( + CORE_POOL_SIZE, + MAX_POOL_SIZE, + KEEP_ALIVE_TIME, + TimeUnit.SECONDS, + new ArrayBlockingQueue<>(WORK_QUEUE_SIZE), + threadFactory, + (r, executor) -> MSG_QUEUE.add(r) + ); + + + // @PostConstruct + public void init() { + initTopicMap(); + loadTags(); + initMqttClient(); + run(); + } + + + /** + * 初始化topicMap + *

+ */ + private void initTopicMap() { + List opcDtos = opcService.queryAll(new HashMap()); + threadPool.setCorePoolSize(opcDtos.size() + 1); + threadPool.setMaximumPoolSize(opcDtos.size() + 10); + opcDtos.forEach(opcDto -> topicMap.put(opcDto.getTopic() == null ? "" : opcDto.getTopic(), new LinkedBlockingQueue<>())); + } + + /** + * 初始化MQTT客户端 + */ + private void initMqttClient() { + mqttClient = MqttClient.builder() + .useMqttVersion3() + .identifier(mqttConfig.getClientId()) + .serverHost(mqttConfig.getUrl()) + .addDisconnectedListener((context -> { + Throwable cause = context.getCause(); + log.error("mqtt client disconnected , {}", cause.getMessage()); + MqttClientReconnector reconnect = context.getReconnector(); + reconnect.reconnect(true); + reconnect.delay(RECONNECT_DELAY, TimeUnit.MILLISECONDS); + })) + .automaticReconnect() + .initialDelay(RECONNECT_DELAY, TimeUnit.MILLISECONDS) + .maxDelay(MAX_RECONNECT_DELAY, TimeUnit.MILLISECONDS) + .applyAutomaticReconnect() + .buildAsync(); + + mqttClient.connectWith() + .simpleAuth() + .username(mqttConfig.getUsername()) + .password(mqttConfig.getPassword().getBytes()) + .applySimpleAuth() + .cleanSession(mqttConfig.getCleanSession()) + .send() + .thenAccept(connAck -> { + log.info("mqtt client connection success."); + subscribeToTopics(Arrays.asList(mqttConfig.getTopics())); + }) + .exceptionally(throwable -> { + log.error("mqtt client connection failed: " + throwable.getMessage(), throwable); + return null; + }); + + mqttClient.publishes(MqttGlobalPublishFilter.ALL, publish -> { + String topic = publish.getTopic().toString(); + String payload = new String(publish.getPayloadAsBytes(), StandardCharsets.UTF_8); + messageArrived(topic, payload); + }); + } + + private void subscribeToTopics(List topics) { + topics.forEach(topic -> mqttClient.subscribeWith() + .topicFilter(topic) + .qos(MqttQos.EXACTLY_ONCE) + .send() + .whenComplete((subAck, throwable) -> { + if (throwable != null) { + log.error("mqtt subscript failed Topic {}, error reason {} ", topic, throwable.getMessage()); + } else { + log.info("mqtt subscript success Topic {}", topic); + } + })); + } + + private void messageArrived(String topic, String payload) { + //接收到消息:先放队列,根据不同topic处理不同处理dd逻辑 + if (topicMap.containsKey(topic)) { + topicMap.get(topic).add(payload); + System.out.println("接收到消息---" + topic + "内容:" + payload); + } else { + log.info("topic---{} , payload----{} ", topic, payload); + } + } + + public CompletableFuture publishMessage(String payload) { + return mqttClient.publishWith() + .topic(PUBLISH_TOPIC) + .payload(payload.getBytes(StandardCharsets.UTF_8)) + .qos(MqttQos.EXACTLY_ONCE) + .send() + .thenAccept(pubAck -> { + log.info("mqtt client publish success Topic {} , Payload: {}", PUBLISH_TOPIC, payload); + }) + .exceptionally(throwable -> { + log.error("mqtt client publish Topic {} ,Payload {} , failed reason {}", PUBLISH_TOPIC, payload, throwable.getMessage()); + return null; + }); + } + + /** + * 为每个Topic初始化线程 + */ + private void run() { + topicMap.forEach((topic, values) -> threadPool.execute(() -> { + log.info("mqtt create Topic thread:{}", topic); + while (true) { + try { + execute(topic, values.take()); + } catch (Exception e) { + log.error("mqtt execute handler failed Topic {} , reason {}", topic, e.getMessage()); + } + } + })); + } + + /** + * 针对topic的消息处理逻辑 + * + * @param topic + * @param body + */ + private void execute(String topic, String body) { + JSONObject msg = JSONObject.parseObject(body); + JSONArray msgValues = msg.getJSONArray("values"); + List tagList = msgValues.toJavaList(Tag.class); + Map> groupTags = tagList.stream().collect(Collectors.groupingBy(tag -> tag.getId().substring(0, TagsUtil.nthIndexOf(tag.getId(), ".", 3)))); + groupTags.forEach((tagId, tags) -> updateDeviceStatus(tagId.substring(TagsUtil.nthIndexOf(tagId, ".", 2) + 1), tags)); + System.out.println("线程名称:'" + Thread.currentThread() + "',接收到消息" + topic + "-" + body + "-"); + } + + /** + * 更新设备数据信息 + * + * @param deviceCode + * @param tags + */ + public void updateDeviceStatus(String deviceCode, List tags) { + setOnline(deviceCode, tags); + setValue(deviceCode, tags); + } + + /** + * 更新设备在线状态 + * + * @param deviceCode + * @param tags + */ + public void setOnline(String deviceCode, List tags) { + Optional heartbeatPresent = tags.stream() + .filter(tag -> tag.getId().contains(HEARTBEAT) || tag.getId().contains("move")) + .map(Tag::isQ) + .findFirst(); + heartbeatPresent.ifPresent(q -> { + Device device = deviceAppService.findDeviceByCode(deviceCode); + if (device != null && device.getDeviceDriver() instanceof AbstractDeviceDriver) { + AbstractDeviceDriver deviceDriver = (AbstractDeviceDriver) device.getDeviceDriver(); + if (!Objects.equals(deviceDriver.online, q)) { + deviceDriver.setOnline(q); + log.info("device : {}, online status: {} ", deviceCode, q); + } + } + }); + } + + /** + * 更新内存中的信号值 + * + * @param deviceCode + * @param tagsValues + */ + private void setValue(String deviceCode, List tagsValues) { + tagsValues.forEach(tag -> { + Object value = TagsUtil.parseValue(tag.getV()); + if (!ObjectUtil.equals(value, ACCESSOR_VALUE.getValue(tag.getId()))) { + logService.deviceExecuteLog(new LuceneLogDto(deviceCode, DeviceLogTypeEnum.MQTT.getCode(), "MQTT上报,信号:" + tag.getId() + ",由" + ACCESSOR_VALUE.getValue(tag.getId()) + "->" + value + ",信号健康值:" + tag.isQ())); + ACCESSOR_VALUE.setValue(tag.getId(), value); + } + }); + } + + + @PreDestroy + public void cleanup() { + if (mqttClient != null) { + unloadTags(); + mqttClient.disconnect().thenAccept(disconnectAck -> { + threadPool.shutdown(); + log.info("Application Close, So MQTT client disconnected."); + }); + } + } + + private void loadTags() { + Map entries = redisTemplateHash.opsForHash().entries(KEY); + entries.forEach((key, value) -> ACCESSOR_VALUE.setValue((String) key, value)); + redisTemplateHash.delete(KEY); + } + + private void unloadTags() { + List allKey = ACCESSOR_VALUE.getAllKey(); + Map map = new HashMap<>(); + allKey.forEach(key -> map.put(key, ACCESSOR_VALUE.getValue(key))); + redisTemplateHash.opsForHash().putAll(KEY, map); + } + + @Override + public void autoInitial() throws Exception { + this.init(); + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/Tag.java b/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/Tag.java new file mode 100644 index 0000000..99a8c83 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/Tag.java @@ -0,0 +1,16 @@ +package org.nl.config.mqtt2; + +import lombok.Data; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/3/5 + */ +@Data +public class Tag { + private String id; + private T v; + private boolean q; + private long t; +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/TagsUtil.java b/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/TagsUtil.java new file mode 100644 index 0000000..5049fba --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/config/mqtt2/TagsUtil.java @@ -0,0 +1,84 @@ +package org.nl.config.mqtt2; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.stream.Collectors; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/3/18 + */ +public class TagsUtil { + + public static final int SCALE = 4; + + + /** + * 获取指定符合索引 + * + * @param text itemId + * @param character 指定符合 + * @param n 第几个富豪 + * @return 索引 + */ + public static int nthIndexOf(String text, String character, int n) { + int position = -1; + do { + position = text.indexOf(character, position + 1); + } while (n-- > 1 && position != -1); + return position; + } + + public static Object parseValue(Object value) { + // 处理字符串类型的值,包括数组和单个字符串 + if (value instanceof String) { + String valueStr = (String) value; + // 转换非标准JSON数组格式的字符串到标准格式 + if (!valueStr.startsWith("[") && valueStr.contains(",")) { + valueStr = "[" + valueStr + "]"; + } + // 尝试解析JSON数组 + if (valueStr.startsWith("[") && valueStr.endsWith("]")) { + try { + JSONArray jsonArray = JSON.parseArray(valueStr); + // 空数组直接返回新的空ArrayList + if (jsonArray.isEmpty()) { + return new ArrayList<>(); + } + // 针对数组中的每个元素进行处理 + return jsonArray.stream().map(element -> { + if (element instanceof Double || element instanceof Float || element instanceof BigDecimal) { + // 对Double和Float类型进行向上取整 + BigDecimal bd = new BigDecimal(element.toString()); + return bd.setScale(SCALE, RoundingMode.HALF_DOWN).doubleValue(); + } else { + // 其他类型直接返回 + return element; + } + }).collect(Collectors.toList()); + } catch (Exception e) { + // 解析失败,返回原始字符串 + return valueStr; + } + } + // 不是数组格式的字符串,直接返回 + return valueStr; + } + + // 处理数值类型,仅对Float和Double进行特殊处理 + if (value instanceof Double || value instanceof Float || value instanceof BigDecimal) { + BigDecimal bd = new BigDecimal(value.toString()); + return bd.setScale(SCALE, RoundingMode.HALF_DOWN).doubleValue(); + } + + // 对于非字符串、非浮点数类型的值,直接返回原值 + return value; + } + + +} \ No newline at end of file diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/common/config/RedisConfig.java b/acs/nladmin-system/src/main/java/org/nl/modules/common/config/RedisConfig.java index cf09c55..fbb8549 100644 --- a/acs/nladmin-system/src/main/java/org/nl/modules/common/config/RedisConfig.java +++ b/acs/nladmin-system/src/main/java/org/nl/modules/common/config/RedisConfig.java @@ -37,6 +37,7 @@ import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; @@ -91,6 +92,25 @@ public class RedisConfig extends CachingConfigurerSupport { return template; } + @SuppressWarnings("all") + @Bean(name = "redisTemplateHash") + @ConditionalOnMissingBean(name = "redisTemplateHash") + public RedisTemplate redisTemplateHash(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(redisConnectionFactory); + + // 设置key和hashKey的序列化方式 + template.setKeySerializer(new StringRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer()); + + // 设置value和hashValue的序列化方式 + template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); + template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); + + template.afterPropertiesSet(); + return template; + } + /** * 自定义缓存key生成策略,默认将使用该策略 */ diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/config/LogMessageConstant.java b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/config/LogMessageConstant.java index 57ae26f..e0d8795 100644 --- a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/config/LogMessageConstant.java +++ b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/config/LogMessageConstant.java @@ -75,6 +75,6 @@ public class LogMessageConstant { /** * 索引路径 */ - public final static String INDEX_DIR = "E:\\lucene\\index"; + public final static String INDEX_DIR = "D:\\lucene\\index"; } diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/config/LuceneAppender.java b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/config/LuceneAppender.java index 943d13d..0aabe62 100644 --- a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/config/LuceneAppender.java +++ b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/config/LuceneAppender.java @@ -79,7 +79,7 @@ public class LuceneAppender extends AppenderBase { //向document对象中添加域。 Map mdcPropertyMap = event.getMDCPropertyMap(); String traceId = mdcPropertyMap.get("traceId"); - System.out.println("---追踪号---"+traceId); +// System.out.println("---追踪号---"+traceId); if (ObjectUtil.isNotEmpty(traceId)) { document.add(new StringField("trace_id", traceId, Field.Store.YES)); } @@ -95,11 +95,23 @@ public class LuceneAppender extends AppenderBase { if (ObjectUtil.isNotEmpty(luceneLogDto.getStatus_code())) { document.add(new StringField("status_code", luceneLogDto.getStatus_code(), Field.Store.YES)); } - if (ObjectUtil.isNotEmpty(luceneLogDto.getRequestparam())) { - document.add(new StringField("requestparam", luceneLogDto.getRequestparam(), Field.Store.YES)); + if (ObjectUtil.isNotEmpty(luceneLogDto.getRequest_param())) { + document.add(new StringField("request_param", luceneLogDto.getRequest_param(), Field.Store.YES)); } - if (ObjectUtil.isNotEmpty(luceneLogDto.getResponseparam())) { - document.add(new StringField("responseparam", luceneLogDto.getResponseparam(), Field.Store.YES)); + if (ObjectUtil.isNotEmpty(luceneLogDto.getResponse_param())) { + document.add(new StringField("response_param", luceneLogDto.getResponse_param(), Field.Store.YES)); + } + if (ObjectUtil.isNotEmpty(luceneLogDto.getRequest_url())) { + document.add(new StringField("request_url", luceneLogDto.getRequest_url(), Field.Store.YES)); + } + if (ObjectUtil.isNotEmpty(luceneLogDto.getDeviceLogType())) { + document.add(new StringField("deviceLogType", luceneLogDto.getDeviceLogType(), Field.Store.YES)); + } + if (ObjectUtil.isNotEmpty(luceneLogDto.getRequest_direction())) { + document.add(new StringField("request_direction", luceneLogDto.getRequest_direction(), Field.Store.YES)); + } + if (ObjectUtil.isNotEmpty(luceneLogDto.getExecuteTime())) { + document.add(new StringField("executeTime", luceneLogDto.getExecuteTime() + "", Field.Store.YES)); } document.add(new StringField("logType", luceneLogDto.getLogType(), Field.Store.YES)); document.add(new StringField("logTime", DateUtil.format(new DateTime(), "yyyy-MM-dd HH:mm:ss.SSS"), Field.Store.YES)); diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/enums/DeviceLogTypeEnum.java b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/enums/DeviceLogTypeEnum.java new file mode 100644 index 0000000..0a038a8 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/enums/DeviceLogTypeEnum.java @@ -0,0 +1,19 @@ +package org.nl.modules.lucene.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * @Description TODO + * @Author Gengby + * @Date 2024/4/10 + */ +@Getter +@RequiredArgsConstructor +public enum DeviceLogTypeEnum { + AUTO_THREAD("auto", "自动线程"), + MQTT("mqtt", "MQTT"); + + private final String code; + private final String name; +} diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/rest/LuceneController.java b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/rest/LuceneController.java index c32761d..75d6160 100644 --- a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/rest/LuceneController.java +++ b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/rest/LuceneController.java @@ -1,10 +1,10 @@ package org.nl.modules.lucene.rest; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.nl.modules.logging.annotation.Log; +import org.nl.modules.lucene.enums.DeviceLogTypeEnum; +import org.nl.modules.lucene.enums.LogTypeEnum; import org.nl.modules.lucene.service.LuceneService; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; @@ -14,12 +14,14 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.util.Arrays; import java.util.Map; +import java.util.stream.Collectors; @RestController @RequiredArgsConstructor -@Api(tags = "日志检索") + @RequestMapping("/api/lucene") @Slf4j public class LuceneController { @@ -27,12 +29,30 @@ public class LuceneController { private final LuceneService luceneService; - @GetMapping("/getAll") - @Log("日志检索") - @ApiOperation("日志检索") - //@PreAuthorize("@el.check('task:list')") public ResponseEntity get(@RequestParam Map whereJson, Pageable page) { return new ResponseEntity<>(luceneService.getAll(whereJson, page), HttpStatus.OK); } + + @GetMapping("/getDeviceLogType") + public ResponseEntity getDeviceLogType() { + return new ResponseEntity<>(Arrays.stream(DeviceLogTypeEnum.values()) + .map(type -> { + Map map = new java.util.HashMap<>(); + map.put("code", type.getCode()); + map.put("name", type.getName()); + return map; + }) + .collect(Collectors.toList()), HttpStatus.OK); + } + + @GetMapping("/getLogTypes") + public ResponseEntity get(@RequestParam Map whereJson) { + return new ResponseEntity<>(Arrays.stream(LogTypeEnum.values()).map(logType -> { + Map map = new java.util.HashMap<>(); + map.put("logType", logType.getDesc()); + return map; + }) + .collect(Collectors.toList()), HttpStatus.OK); + } } diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/LuceneExecuteLogService.java b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/LuceneExecuteLogService.java index e4b0db1..52ecbae 100644 --- a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/LuceneExecuteLogService.java +++ b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/LuceneExecuteLogService.java @@ -1,6 +1,5 @@ package org.nl.modules.lucene.service; - import org.nl.modules.lucene.service.dto.LuceneLogDto; public interface LuceneExecuteLogService { diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/dto/LuceneLogDto.java b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/dto/LuceneLogDto.java index d10fbe4..0e4315c 100644 --- a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/dto/LuceneLogDto.java +++ b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/dto/LuceneLogDto.java @@ -4,6 +4,7 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.nl.modules.lucene.enums.DeviceLogTypeEnum; @Data @Builder @@ -11,96 +12,80 @@ import lombok.NoArgsConstructor; @AllArgsConstructor public class LuceneLogDto { - /* 日志标识 */ - private String log_uuid; - /*日志类型*/ + /** + * 日志类型 + */ private String logType; - /*设备编号*/ + + /** + * 设备编号 + */ private String device_code; - /*内容详情*/ + + /** + * 内容详情 + */ private String content; - /* 任务编码 */ - private String task_code; - - /* 指令编码 */ - private String instruct_code; - - /* 任务标识 */ - private String task_id; - - /* 载具号 */ - private String vehicle_code; - - /* 备注 */ - private String remark; - - /* 日志类型 */ - private String log_type; - - /* 方法 */ + /** + * 方法 + */ private String method; - /* 请求参数 */ - private String requestparam; + /** + * 请求参数 + */ + private String request_param; - /* 响应参数 */ - private String responseparam; + /** + * 响应参数 + */ + private String response_param; - /* 请求地址 */ - private String requesturl; + /** + * 请求路径 + */ + private String request_url; - /* 状态码 */ + + /** + * 状态码 + */ private String status_code; - /* 是否删除 1:是;0:否 */ - private String is_delete; + /** + * 设备日志类型 + */ + private String deviceLogType; - /* 创建者 */ - private String create_by; + /** + * 请求方向 + */ + private String request_direction; - /* 创建时间 YYYY-MM-DD hh:mm:ss */ - private String create_time; + /** + * 执行时间 + */ + private long executeTime; - /* 修改者 */ - private String update_by; - - /* 修改时间 */ - private String update_time; - - - public LuceneLogDto(final String opc_server_code, final String opc_plc_code, - final String device_code, final String to_home, final String last_home, - final String home) { - super(); - this.device_code = device_code; - this.content = "信号 [" - + opc_server_code + "." - + opc_plc_code + "." - + device_code + "." - + to_home + "] 发生变更 " - + last_home + " -> " - + home; - } public LuceneLogDto(final String device_code, final String remark) { super(); this.device_code = device_code; + this.deviceLogType = DeviceLogTypeEnum.AUTO_THREAD.getCode(); this.content = "设备 [" + device_code + "] - " + remark; } - public LuceneLogDto(final LuceneLogDto dto) { + public LuceneLogDto(final String device_code, final String device_log_type, final String remark) { super(); this.device_code = device_code; - this.method = method; - + this.deviceLogType = device_log_type; this.content = "设备 [" + device_code + "] - " + remark; } - } diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/impl/LuceneServiceImpl.java b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/impl/LuceneServiceImpl.java index 6c10ee4..e33888e 100644 --- a/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/impl/LuceneServiceImpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/modules/lucene/service/impl/LuceneServiceImpl.java @@ -12,6 +12,9 @@ import org.apache.lucene.search.*; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.BytesRef; import org.nl.modules.lucene.service.LuceneService; +import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -26,14 +29,17 @@ import java.util.*; @Slf4j public class LuceneServiceImpl implements LuceneService { - //日志索引目录 - - @Override public Map getAll(Map whereJson, Pageable page) { //获取要查询的路径,也就是索引所在的位置 try { - FSDirectory directory = FSDirectory.open(Paths.get("C:\\acs\\lucene\\index")); + Resource resource = new ClassPathResource("config/application.yml"); + YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean(); + yamlPropertiesFactoryBean.setResources(resource); + Properties properties = yamlPropertiesFactoryBean.getObject(); + // 获取配置值 + String luceneDir = properties.getProperty("lucene.index.path"); + FSDirectory directory = FSDirectory.open(Paths.get(luceneDir)); DirectoryReader open = DirectoryReader.open(directory); IndexSearcher searcher = new IndexSearcher(open); // 实际上Lucene本身不支持分页。因此我们需要自己进行逻辑分页。我们要准备分页参数: @@ -45,48 +51,55 @@ public class LuceneServiceImpl implements LuceneService { String startDate = (String) whereJson.get("begin_time"); String endDate = (String) whereJson.get("end_time"); - if (startDate == null){ - Calendar calendar=Calendar.getInstance(); + if (startDate == null) { + Calendar calendar = Calendar.getInstance(); calendar.set(1970, 0, 1); - startDate = DateUtil.format(calendar.getTime(),"yyyy-MM-dd HH:mm:ss.SSS"); - }else{ + startDate = DateUtil.format(calendar.getTime(), "yyyy-MM-dd HH:mm:ss.SSS"); + } else { startDate = getDate(startDate); } - if (endDate == null){ - endDate = DateUtil.format(new DateTime(),"yyyy-MM-dd HH:mm:ss.SSS"); + if (endDate == null) { + endDate = DateUtil.format(new DateTime(), "yyyy-MM-dd HH:mm:ss.SSS"); } else { endDate = getDate(endDate); } TermRangeQuery termRangeQuery = new TermRangeQuery("logTime", new BytesRef(startDate), new BytesRef(endDate), true, true); - booleanQueryBuilder.add(termRangeQuery,BooleanClause.Occur.MUST); - if (whereJson.get("device_code") != null){ + booleanQueryBuilder.add(termRangeQuery, BooleanClause.Occur.MUST); + if (whereJson.get("logType") != null) { + Query termQuery = new TermQuery(new Term("logType", (String) whereJson.get("logType"))); + booleanQueryBuilder.add(termQuery, BooleanClause.Occur.MUST); + } + if (whereJson.get("device_code") != null) { Query termQuery = new TermQuery(new Term("device_code", (String) whereJson.get("device_code"))); - booleanQueryBuilder.add(termQuery,BooleanClause.Occur.MUST); + booleanQueryBuilder.add(termQuery, BooleanClause.Occur.MUST); } - if (whereJson.get("method") != null){ - Query termQuery = new TermQuery(new Term("method", (String) whereJson.get("method"))); - booleanQueryBuilder.add(termQuery,BooleanClause.Occur.MUST); + if (whereJson.get("deviceLogType") != null) { + Query termQuery = new TermQuery(new Term("deviceLogType", (String) whereJson.get("deviceLogType"))); + booleanQueryBuilder.add(termQuery, BooleanClause.Occur.MUST); } - if (whereJson.get("status_code") != null){ - Query termQuery = new TermQuery(new Term("status_code", (String) whereJson.get("status_code"))); - booleanQueryBuilder.add(termQuery,BooleanClause.Occur.MUST); + if (whereJson.get("method") != null) { + WildcardQuery termQuery = new WildcardQuery(new Term("method", "*" + (String) whereJson.get("method") + "*")); + booleanQueryBuilder.add(termQuery, BooleanClause.Occur.MUST); } - if (whereJson.get("requestparam") != null){ - WildcardQuery query = new WildcardQuery(new Term("requestparam", "*"+(String) whereJson.get("requestparam")+"*")); - booleanQueryBuilder.add(query,BooleanClause.Occur.MUST); + if (whereJson.get("request_url") != null) { + WildcardQuery termQuery = new WildcardQuery(new Term("request_url", "*" + (String) whereJson.get("request_url") + "*")); + booleanQueryBuilder.add(termQuery, BooleanClause.Occur.MUST); } - if (whereJson.get("responseparam") != null){ - WildcardQuery query = new WildcardQuery(new Term("responseparam", "*"+(String) whereJson.get("responseparam")+"*")); - booleanQueryBuilder.add(query,BooleanClause.Occur.MUST); + if (whereJson.get("request_direction") != null) { + Query termQuery = new TermQuery(new Term("request_direction", (String) whereJson.get("request_direction"))); + booleanQueryBuilder.add(termQuery, BooleanClause.Occur.MUST); + } + if (whereJson.get("request_param") != null) { + WildcardQuery termQuery = new WildcardQuery(new Term("request_param", "*" + (String) whereJson.get("request_param") + "*")); + booleanQueryBuilder.add(termQuery, BooleanClause.Occur.MUST); } if (whereJson.get("blurry") != null) { - WildcardQuery query = new WildcardQuery(new Term("fieldContent", "*"+(String) whereJson.get("blurry")+"*")); + WildcardQuery query = new WildcardQuery(new Term("fieldContent", "*" + (String) whereJson.get("blurry") + "*")); booleanQueryBuilder.add(query, BooleanClause.Occur.MUST); } - - TopFieldCollector collector = TopFieldCollector.create(new Sort(new SortField("logTime", SortField.Type.LONG,true)), 20000, 0); + TopFieldCollector collector = TopFieldCollector.create(new Sort(new SortField("logTime", SortField.Type.LONG, true)), 20000, 0); searcher.search(booleanQueryBuilder.build(), collector); - TopDocs topDocs = collector.topDocs(pageNum*pageSize, pageSize); + TopDocs topDocs = collector.topDocs(pageNum * pageSize, pageSize); int totalSize = collector.getTotalHits(); ScoreDoc[] scoreDocs = topDocs.scoreDocs; @@ -94,14 +107,18 @@ public class LuceneServiceImpl implements LuceneService { for (ScoreDoc scoreDoc : scoreDocs) { Document doc = open.document(scoreDoc.doc); JSONObject object = new JSONObject(); - object.put("content",doc.get("fieldContent")); - object.put("device_code",doc.get("device_code")); - object.put("logTime",doc.get("logTime")); - object.put("method",doc.get("method")); - object.put("status_code",doc.get("status_code")); - object.put("requestparam",doc.get("requestparam")); - object.put("responseparam",doc.get("responseparam")); - if(doc.get("fieldContent") != null) { + object.put("content", doc.get("fieldContent")); + object.put("device_code", doc.get("device_code")); + object.put("deviceLogType", doc.get("deviceLogType")); + object.put("logTime", doc.get("logTime")); + object.put("method", doc.get("method")); + object.put("request_url", doc.get("request_url")); + object.put("status_code", doc.get("status_code")); + object.put("request_param", doc.get("request_param")); + object.put("response_param", doc.get("response_param")); + object.put("request_direction", doc.get("request_direction")); + object.put("executeTime", doc.get("executeTime")); + if (doc.get("fieldContent") != null) { list.add(object); } } diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/AutoCleanLuceneLog.java b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/AutoCleanLuceneLog.java new file mode 100644 index 0000000..041d307 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/AutoCleanLuceneLog.java @@ -0,0 +1,64 @@ +package org.nl.modules.quartz.task; + +import cn.hutool.core.date.DateUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.*; +import org.apache.lucene.store.FSDirectory; +import org.apache.lucene.util.BytesRef; +import org.nl.modules.lucene.config.LuceneAppender; +import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; + +import java.nio.file.Paths; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.Properties; + + +/** + * @author onepiece + */ +@Slf4j +@Component +public class AutoCleanLuceneLog { + + private static final long MAX_FILE_AGE_DAYS = 10; + + public void run() { + try { + Resource resource = new ClassPathResource("config/application.yml"); + YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean(); + yamlPropertiesFactoryBean.setResources(resource); + Properties properties = yamlPropertiesFactoryBean.getObject(); + String logDirectory = properties.getProperty("lucene.index.path"); + + Instant now = Instant.now(); + Instant cutoffTime = now.minus(MAX_FILE_AGE_DAYS, ChronoUnit.DAYS); + String cutoffTimeStr = DateUtil.format(Date.from(cutoffTime), "yyyy-MM-dd HH:mm:ss.SSS"); + + FSDirectory dir = FSDirectory.open(Paths.get(logDirectory)); + IndexWriter writer = LuceneAppender.indexWriter; + + try (IndexReader reader = DirectoryReader.open(dir)) { + IndexSearcher searcher = new IndexSearcher(reader); + Query query = new TermRangeQuery("logTime", new BytesRef(""), new BytesRef(cutoffTimeStr), true, true); + TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE); + for (ScoreDoc scoreDoc : topDocs.scoreDocs) { + Document doc = searcher.doc(scoreDoc.doc); + writer.deleteDocuments(new Term("logTime", doc.get("logTime"))); + } + } + writer.commit(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/QueryXGTaskStatus.java b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/QueryXGTaskStatus.java index 41fc084..0af1205 100644 --- a/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/QueryXGTaskStatus.java +++ b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/QueryXGTaskStatus.java @@ -1,5 +1,6 @@ package org.nl.modules.quartz.task; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpResponse; @@ -8,13 +9,21 @@ import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.nl.acs.agv.server.XianGongAgvService; +import org.nl.acs.ext.UnifiedResponse; import org.nl.acs.ext.wms.service.AcsToWmsService; import org.nl.acs.instruction.service.InstructionService; import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.service.ParamService; +import org.nl.modules.wql.util.SpringContextHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.List; +import java.util.stream.Collectors; + /** * 查询AGV任务状态 */ @@ -23,56 +32,106 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor public class QueryXGTaskStatus { - private final InstructionService instructionService; + @Autowired + private InstructionService instructionService; + @Autowired + private XianGongAgvService agvService; - private final XianGongAgvService agvService; - - public void run() throws Exception { - - HttpResponse response = agvService.queryXZAgvInstStatus(); - JSONObject jo = JSONArray.parseObject(response.body()); - - JSONArray ja = JSONArray.parseArray(jo.getString("list")); - for (int i = 0; i < ja.size(); i++) { - JSONObject one = (JSONObject) ja.get(i); - String inst_code = one.getString("id"); - Instruction inst = instructionService.findByCodeFromCache(inst_code); - if (ObjectUtil.isEmpty(inst)) - continue; - - String state = one.getString("state"); - if (!StrUtil.isEmpty(one.getString("vehicle"))) { - String carno = one.getString("vehicle"); - inst.setCarno(carno); - } - -// 已创建=CREATED, -// 待分配=TOBEDISPATCHED, -// 正在执行=RUNNING, -// 完成=FINISHED, -// 失败=FAILED(主动失败), -// 终止=STOPPED(被人为终止), -// 无法执行=Error(参数错误), -// 等待=WAITING - - //执行中 - if ("RUNNING".equals(state) || "CREATED".equals(state) || "TOBEDISPATCHED".equals(state) || "WAITING".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 ("STOPPED".equals(state) || "FAILED".equals(state) || "Error".equals(state)) { - if (inst != null) { - inst.setInstruction_status("1"); - instructionService.update(inst); + public void run() { + try { + List allInstFromCache = instructionService.findAllInstFromCache(); + for (Instruction instruction : allInstFromCache) { + UnifiedResponse resp = agvService.queryXZAgvInstStatusByCode(instruction.getInstruction_code(), JSONObject.class); + if (resp.isSuccess()) { + // 已创建=CREATED, + // 待分配=TOBEDISPATCHED, + // 正在执行=RUNNING, + // 完成=FINISHED, + // 失败=FAILED(主动失败), + // 终止=STOPPED(被人为终止), + // 无法执行=Error(参数错误), + // 等待=WAITING + //执行中 + String state = resp.getData().getString("state"); + String carNo = resp.getData().getString("vehicle"); + String instructionCode = resp.getData().getString("id"); + if ("RUNNING".equals(state) || "CREATED".equals(state) || "TOBEDISPATCHED".equals(state) || "WAITING".equals(state)) { + if (!instruction.getInstruction_status().equals("1")) { + instruction.setInstruction_status("1"); + instruction.setCarno(carNo); + instructionService.update(instruction); + } + } else if ("FINISHED".equals(state)) { + instruction.setInstruction_status("2"); + try { + instructionService.finish(instruction); + } catch (Exception e) { + log.error("执行完成,但无法更新状态,可能由于参数错误导致的异常"); + e.printStackTrace(); + } + } else if ("STOPPED".equals(state) || "FAILED".equals(state) || "Error".equals(state)) { + if (!instruction.getInstruction_status().equals("1")) { + instruction.setInstruction_status("1"); + instructionService.update(instruction); + } + } } } +// UnifiedResponse resp = agvService.queryXZAgvInstStatus(JSONObject.class); +// if (resp.isSuccess()) { +// JSONObject data = resp.getData(); +// JSONArray list = data.getJSONArray("list"); +// if (list == null) return; +// for (int i = 0; i < list.size(); i++) { +// JSONObject one = list.getJSONObject(i); +// String inst_code = one.getString("id"); +// Instruction inst = instructionService.findByCodeFromCache(inst_code); +// +// if (ObjectUtil.isEmpty(inst)) continue; +// +// //子任务状态 待以后处理 +// JSONArray blocks = JSONArray.parseArray(one.getString("blocks")); +// for (int j = 0; j < blocks.size(); j++) { +// JSONObject blocksjo = (JSONObject) blocks.get(j); +// String blockId = blocksjo.getString("blockId"); +// String device_code = blocksjo.getString("location"); +// String state = blocksjo.getString("state"); +// } +// +// String state = one.getString("state"); +// if (!StrUtil.isEmpty(one.getString("vehicle"))) { +// String carno = one.getString("vehicle"); +// inst.setCarno(carno); +// } +//// 已创建=CREATED, +//// 待分配=TOBEDISPATCHED, +//// 正在执行=RUNNING, +//// 完成=FINISHED, +//// 失败=FAILED(主动失败), +//// 终止=STOPPED(被人为终止), +//// 无法执行=Error(参数错误), +//// 等待=WAITING +// //执行中 +// if ("RUNNING".equals(state) || "CREATED".equals(state) || "TOBEDISPATCHED".equals(state) || "WAITING".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 ("STOPPED".equals(state) || "FAILED".equals(state) || "Error".equals(state)) { +// if (inst != null) { +// inst.setInstruction_status("1"); +// instructionService.update(inst); +// } +// } +// } +// } + } catch (Exception e) { + } - } } diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/QueryXZAgvDeviceStatus.java b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/QueryXZAgvDeviceStatus.java new file mode 100644 index 0000000..6471659 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/modules/quartz/task/QueryXZAgvDeviceStatus.java @@ -0,0 +1,122 @@ +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.XianGongAgvService; +import org.nl.acs.device_driver.basedriver.agv.xg_agv.XianGongAgvDeviceDriver; +import org.nl.acs.ext.UnifiedResponse; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceAppService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.math.RoundingMode; +import java.text.DecimalFormat; + +/** + * 查询先工AGV设备状态 + */ +@Slf4j +@Component +public class QueryXZAgvDeviceStatus { + + @Autowired + private XianGongAgvService agvService; + @Autowired + private DeviceAppService deviceAppService; + @Autowired + private InstructionService instructionService; + + + public void run() { + try { + UnifiedResponse response = agvService.queryXZAgvDeviceStatus(null, JSONObject.class); + if (response.isSuccess()) { + JSONObject body = response.getData(); + JSONArray ja = body.getJSONArray("report"); + for (int i = 0; i < ja.size(); i++) { + JSONObject jo = ja.getJSONObject(i); + //机器人编码 + String agv_code = jo.getString("uuid"); + //机器人详细状态信息 + JSONObject rbk_report = jo.getJSONObject("rbk_report"); + //是否正在充电 + Boolean charging = rbk_report.getBoolean("charging"); + //角度 + Double angle = rbk_report.getDouble("angle"); + //电池电量(0-1) + Double battery_level = rbk_report.getDouble("battery_level"); + //当前开机时间 ms + Integer time = rbk_report.getInteger("time"); + //累计运行时间 ms + Integer total_time = rbk_report.getInteger("total_time"); + //今日累计行驶里程, 单位 m + Double today_odo = rbk_report.getDouble("today_odo"); + //累计行驶里程 + Integer odo = rbk_report.getInteger("odo"); + //是否正在执行任务 + Boolean procBusiness = jo.getBoolean("procBusiness"); + //agv是否故障 + Boolean is_error = jo.getBoolean("is_error"); + //执行运单信息 + JSONObject current_order = jo.getJSONObject("current_order"); + Integer connectionStatus = jo.getInteger("connection_status"); + String inst_code = current_order.getString("id"); + Instruction instruction = instructionService.findByCodeFromCache(inst_code); + String taskCode = "0"; + if (instruction != null) { + taskCode = instruction.getTask_code(); + } + DecimalFormat hisFormat = new DecimalFormat("########.###"); + hisFormat.setRoundingMode(RoundingMode.DOWN); + //x坐标 + Double x = rbk_report.getDouble("x"); + //y坐标 + Double y = rbk_report.getDouble("y"); + String status = "0"; + if (connectionStatus == 0) { + status = "5"; + } else { + if (procBusiness && !is_error) { + //工作中 + status = "1"; + } else { + if (charging) { + //充电中 + status = "2"; + } else { + if (is_error) { + //故障 + status = "3"; + } else { + //休息中 + status = "4"; + } + } + } + } + Device device = deviceAppService.findDeviceByCode(agv_code); + if (device != null && device.getDeviceDriver() instanceof XianGongAgvDeviceDriver) { + XianGongAgvDeviceDriver xgAGV = (XianGongAgvDeviceDriver) device.getDeviceDriver(); + xgAGV.setTaskCode(taskCode); + xgAGV.setBattery_level(battery_level); + xgAGV.setAngle(angle); + xgAGV.setTime(time); + xgAGV.setTotal_time(total_time); + xgAGV.setToday_odo(today_odo); + xgAGV.setOdo(odo); + xgAGV.setX(x); + xgAGV.setY(y); + xgAGV.setStatus(Integer.parseInt(status)); + } + } + } + } catch (Exception e) { + System.out.println("出现异常"); + e.printStackTrace(); + } + } +} diff --git a/acs/nladmin-system/src/main/resources/config/application-dev2.yml b/acs/nladmin-system/src/main/resources/config/application-dev2.yml index 04eaae3..ba3627a 100644 --- a/acs/nladmin-system/src/main/resources/config/application-dev2.yml +++ b/acs/nladmin-system/src/main/resources/config/application-dev2.yml @@ -6,7 +6,7 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy - url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:zhongdianke_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true + url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:sdk_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true username: ${DB_USER:root} password: ${DB_PWD:password} # 初始连接数 @@ -52,11 +52,25 @@ spring: multi-statement-allow: true redis: #数据库索引 - database: ${REDIS_DB:15} + database: ${REDIS_DB:3} host: ${REDIS_HOST:127.0.0.1} port: ${REDIS_PORT:6379} password: ${REDIS_PWD:} + mqtt: + active: true + username: root + password: 123456 + cleanSession: true + url: 192.168.81.251 + clientId: sdk_mqtt21 + topics: + - SDK/# + qoss: + - 2 + timeout: 30 + keepalive: 15 + # 登录相关配置 login: # 登录缓存 diff --git a/acs/nladmin-system/src/main/resources/config/application-prod.yml b/acs/nladmin-system/src/main/resources/config/application-prod.yml index 4fcaa39..77d8caf 100644 --- a/acs/nladmin-system/src/main/resources/config/application-prod.yml +++ b/acs/nladmin-system/src/main/resources/config/application-prod.yml @@ -6,9 +6,9 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy - url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true + url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:sdk_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true username: ${DB_USER:root} - password: ${DB_PWD:123456} + password: ${DB_PWD:password} # 初始连接数 initial-size: 5 # 最小连接数 @@ -52,11 +52,25 @@ spring: multi-statement-allow: true redis: #数据库索引 - database: ${REDIS_DB:15} + database: ${REDIS_DB:3} host: ${REDIS_HOST:127.0.0.1} port: ${REDIS_PORT:6379} password: ${REDIS_PWD:} + mqtt: + active: true + username: root + password: 123456 + cleanSession: false + url: 127.0.0.1 + clientId: sdk_mqtt21 + topics: + - SDK/# + qoss: + - 2 + timeout: 30 + keepalive: 15 + # 登录相关配置 login: # 登录缓存 diff --git a/acs/nladmin-ui/public/favicon.ico b/acs/nladmin-ui/public/favicon.ico index 7675aa6..594b34a 100644 Binary files a/acs/nladmin-ui/public/favicon.ico and b/acs/nladmin-ui/public/favicon.ico differ diff --git a/acs/nladmin-ui/src/assets/images/logo.png b/acs/nladmin-ui/src/assets/images/logo.png index 7675aa6..0503a9a 100644 Binary files a/acs/nladmin-ui/src/assets/images/logo.png and b/acs/nladmin-ui/src/assets/images/logo.png differ diff --git a/acs/nladmin-ui/src/views/acs/device/config.vue b/acs/nladmin-ui/src/views/acs/device/config.vue index 036d725..20dfacb 100644 --- a/acs/nladmin-ui/src/views/acs/device/config.vue +++ b/acs/nladmin-ui/src/views/acs/device/config.vue @@ -22,13 +22,13 @@ :value="item.value" /> - + - - + + @@ -36,8 +36,8 @@ - - + + @@ -63,7 +63,7 @@ - + @@ -71,8 +71,8 @@ + + diff --git a/acs/nladmin-ui/src/views/acs/device/driver/xg/xg_agv.vue b/acs/nladmin-ui/src/views/acs/device/driver/xg/xg_agv.vue new file mode 100644 index 0000000..4635535 --- /dev/null +++ b/acs/nladmin-ui/src/views/acs/device/driver/xg/xg_agv.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/acs/nladmin-ui/src/views/acs/device/opc/index.vue b/acs/nladmin-ui/src/views/acs/device/opc/index.vue index 8e74590..27cb84d 100644 --- a/acs/nladmin-ui/src/views/acs/device/opc/index.vue +++ b/acs/nladmin-ui/src/views/acs/device/opc/index.vue @@ -14,9 +14,9 @@ class="filter-item" @keyup.enter.native="crud.toQuery" /> - + - + - + - + - + + + + - + - + 详情 - + - + - + - +