src/main/java/com/zy/controller/MonitorController.java
@@ -75,13 +75,16 @@ * 获取其他信息 */ @GetMapping("/other") public R monitorOther(@RequestParam("crnId") Integer crnId, @RequestParam("ledId") Integer sta) { public R monitorOther(@RequestParam("crnId") Integer crnId, @RequestParam("ledId") String ledIdString) { Integer ledId = 0; for (LedSlave led : slaveProperties.getLed()) { for (Integer staNo : led.getStaArr()) { if (staNo.equals(sta)) { ledId = led.getId(); break; String[] ledIds = ledIdString.split(","); for (String id : ledIds) { for (LedSlave led : slaveProperties.getLed()) { for (Integer staNo : led.getStaArr()) { if (staNo.equals(Integer.parseInt(id))) { ledId = led.getId(); break; } } } } @@ -261,15 +264,18 @@ * 获取其他信息 */ @GetMapping("/led") public R monitorLed(@RequestParam("ledId") Integer ledId) { public R monitorLed(@RequestParam("ledId") String ledIdString) { String[] ledIds = ledIdString.split(","); String ledContent = ""; List<LedCommand> commandList = null; for (LedSlave slave : slaveProperties.getLed()) { if (slave.getStaArr().contains(ledId)) { LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, slave.getId()); if (null != ledThread) { ledContent = ledThread.getStringBuffer().toString(); commandList = ledThread.getCommandList(); for(String ledId: ledIds) { for (LedSlave slave : slaveProperties.getLed()) { if (slave.getStaArr().contains(Integer.parseInt(ledId))) { LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, slave.getId()); if (null != ledThread) { ledContent = ledThread.getStringBuffer().toString(); commandList = ledThread.getCommandList(); } } } } @@ -280,13 +286,16 @@ * 异常通知 */ @GetMapping("/led/error") public R monitorLedError(@RequestParam("ledId") Integer ledId) { public R monitorLedError(@RequestParam("ledId") String ledIdString) { String errorMsg = ""; for (LedSlave slave : slaveProperties.getLed()) { if (slave.getStaArr().contains(ledId)) { LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, slave.getId()); if (null != ledThread) { errorMsg = ledThread.getErrorMsg().toString(); String[] ledIds = ledIdString.split(","); for(String ledId: ledIds) { for (LedSlave slave : slaveProperties.getLed()) { if (slave.getStaArr().contains(Integer.parseInt(ledId))) { LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, slave.getId()); if (null != ledThread) { errorMsg = ledThread.getErrorMsg().toString(); } } } } src/main/java/com/zy/controller/RcsController.java
New file @@ -0,0 +1,30 @@ package com.zy.controller; import com.alibaba.fastjson.JSONObject; import com.zy.common.web.BaseController; import com.zy.entity.RcsReporterTask; import com.zy.entity.RcsReturn; import com.zy.service.RcsService; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController @Slf4j public class RcsController extends BaseController { @Resource private RcsService rcsService; // 反馈任务执行结果 @PostMapping("/api/robot/reporter/task") public RcsReturn reporterTask(@RequestBody RcsReporterTask param){ log.info("agv任务执行反馈请求:{}",JSONObject.toJSONString(param)); return rcsService.reporterTask(param); } } src/main/java/com/zy/controller/SiteController.java
@@ -153,7 +153,7 @@ } @PostMapping("/detl/update") @ManagerAuth(memo = "修改站点数据") @ManagerAuth(memo = "修改站点数据",value = ManagerAuth.Auth.NONE) public R siteDetlUpdate(@RequestParam Integer siteId, @RequestParam Integer workNo, @RequestParam Short staNo, src/main/java/com/zy/core/ServerBootstrap.java
@@ -58,9 +58,9 @@ MessageQueue.init(SlaveType.Crn, crn); } // 初始化Rgv小车mq for (Slave rgv : slaveProperties.getRgv()) { MessageQueue.init(SlaveType.Rgv, rgv); } // for (Slave rgv : slaveProperties.getRgv()) { // MessageQueue.init(SlaveType.Rgv, rgv); // } // 初始化输送线mq for (Slave devp : slaveProperties.getDevp()) { MessageQueue.init(SlaveType.Devp, devp); src/main/java/com/zy/core/thread/SiemensDevpThread.java
@@ -182,8 +182,8 @@ */ private void read() { // 站点信息 OperateResultExOne<byte[]> result = siemensS7Net.Read("DB101.0", (short) (8*5)); // 读货位信息反馈 OperateResultExOne<byte[]> result = siemensS7Net.Read("DB101.0", (short) (staNos.size() * 8)); if (result.IsSuccess) { for (int i = 0; i < staNos.size(); i++) { Integer siteId = staNos.get(i); // 站点编号 @@ -220,7 +220,7 @@ return; } // 条码扫描器 // 条码信息反馈 OperateResultExOne<byte[]> barcodeResult = siemensS7Net.Read("DB101.600", (short) (BarcodeList.size() * 10)); if (barcodeResult.IsSuccess) { for (int i = 0; i < BarcodeList.size(); i++) { src/main/java/com/zy/entity/ApiLog.java
New file @@ -0,0 +1,198 @@ package com.zy.entity; import com.baomidou.mybatisplus.annotations.TableField; import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import com.baomidou.mybatisplus.enums.IdType; import com.core.common.Cools; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date; @Data @TableName("man_api_log") public class ApiLog implements Serializable { private static final long serialVersionUID = 1L; /** * ID */ @ApiModelProperty(value = "ID") @TableId(value = "id", type = IdType.AUTO) private Long id; /** * 日志编号 */ @ApiModelProperty(value = "日志编号") private String uuid; /** * 名称空间 */ @ApiModelProperty(value = "名称空间") private String namespace; /** * 接口地址 */ @ApiModelProperty(value = "接口地址") private String url; /** * 平台密钥 */ @ApiModelProperty(value = "平台密钥") private String appkey; /** * 时间戳 */ @ApiModelProperty(value = "时间戳") private String timestamp; /** * 客户端IP */ @ApiModelProperty(value = "客户端IP") @TableField("client_ip") private String clientIp; /** * 请求内容 */ @ApiModelProperty(value = "请求内容") private String request; /** * 响应内容 */ @ApiModelProperty(value = "响应内容") private String response; /** * 异常内容 */ @ApiModelProperty(value = "异常内容") private String err; /** * 结果 1: 成功 0: 失败 */ @ApiModelProperty(value = "结果 1: 成功 0: 失败 ") private Integer result; /** * 状态 1: 正常 0: 禁用 */ @ApiModelProperty(value = "状态 1: 正常 0: 禁用 ") private Integer status; /** * 添加时间 */ @ApiModelProperty(value = "添加时间") @TableField("create_time") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; /** * 修改时间 */ @ApiModelProperty(value = "修改时间") @TableField("update_time") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date updateTime; /** * 备注 */ @ApiModelProperty(value = "备注") private String memo; public ApiLog() { } public ApiLog(String uuid, String namespace, String url, String appkey, String timestamp, String clientIp, String request, String response, String err, Integer result, Integer status, Date createTime, Date updateTime, String memo) { this.uuid = uuid; this.namespace = namespace; this.url = url; this.appkey = appkey; this.timestamp = timestamp; this.clientIp = clientIp; this.request = request; this.response = response; this.err = err; this.result = result; this.status = status; this.createTime = createTime; this.updateTime = updateTime; this.memo = memo; } // ApiLog apiLog = new ApiLog( // null, // 日志编号 // null, // 名称空间 // null, // 接口地址 // null, // 平台密钥 // null, // 时间戳 // null, // 客户端IP // null, // 请求内容 // null, // 响应内容 // null, // 异常内容 // null, // 结果 // null, // 状态 // null, // 添加时间 // null, // 修改时间 // null // 备注 // ); public String getResult$() { if (null == this.result) { return null; } switch (this.result) { case 1: return "成功"; case 0: return "失败"; default: return String.valueOf(this.result); } } public String getStatus$() { if (null == this.status) { return null; } switch (this.status) { case 1: return "正常"; case 0: return "禁用"; default: return String.valueOf(this.status); } } public String getCreateTime$() { if (Cools.isEmpty(this.createTime)) { return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime); } public String getUpdateTime$() { if (Cools.isEmpty(this.updateTime)) { return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime); } } src/main/java/com/zy/entity/RcsReporterTask.java
New file @@ -0,0 +1,18 @@ package com.zy.entity; import com.alibaba.fastjson.JSONObject; import lombok.Data; // 任务执行反馈 @Data public class RcsReporterTask { // 任务号 private String robotTaskCode; // 当前执行任务的机器人唯一标识。 private String singleRobotCode; // 目标路径序列,0 起点序号,1 终点序号。 private Integer currentSeq; // 详细信息 private JSONObject extra; } src/main/java/com/zy/entity/RcsReturn.java
New file @@ -0,0 +1,20 @@ package com.zy.entity; import com.alibaba.fastjson.JSONObject; import lombok.Data; // 海康返回 @Data public class RcsReturn { // SUCCESS 成功 // Err_TaskTypeNotSupport 任务类型不支持 // Err_RobotGroupsNotMatch 机器人资源组编号与任务不匹配,无法调度 // Err_RobotCodeNotMatch 机器人编号与任务不匹配,无法调度 // Err_TargetRouteError 任务路径参数有误 private String code; private String message; private JSONObject data; } src/main/java/com/zy/enums/RcsRetMethodEnum.java
New file @@ -0,0 +1,38 @@ package com.zy.enums; public enum RcsRetMethodEnum { TASK_START("start", "任务开始"), TASK_END("end", "任务完成"), TASK_OUT_BIN("outbin", "走出储位"), APPLY_IN_STATION("applyInStation", "入站请求"), APPLY_OFF_STATION("applyOutStation", "离站请求"), ARRIVE_ON_STATION("arriveOnStation", "到站完成"), ARRIVE_OFF_STATION("arriveOffStation", "离站完成"); private String code; private String message; RcsRetMethodEnum(String code, String message) { this.code = code; this.message = message; } public static RcsRetMethodEnum getEnum(String code) { for (RcsRetMethodEnum method : RcsRetMethodEnum.values()) { if (method.getCode().equals(code)) { return method; } } return null; } public String getCode() { return code; } public String getMessage() { return message; } } src/main/java/com/zy/mapper/ApiLogMapper.java
New file @@ -0,0 +1,14 @@ package com.zy.mapper; import com.baomidou.mybatisplus.mapper.BaseMapper; import com.zy.entity.ApiLog; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; @Mapper @Repository public interface ApiLogMapper extends BaseMapper<ApiLog> { int clearWeekBefore(); } src/main/java/com/zy/service/ApiLogService.java
New file @@ -0,0 +1,12 @@ package com.zy.service; import com.baomidou.mybatisplus.service.IService; import com.zy.entity.ApiLog; public interface ApiLogService extends IService<ApiLog> { void save(String namespace, String url, String appkey, String ip, String request, String response, boolean success); boolean clearWeekBefore(); } src/main/java/com/zy/service/RcsService.java
New file @@ -0,0 +1,16 @@ package com.zy.service; import com.zy.entity.RcsReporterTask; import com.zy.entity.RcsReturn; public interface RcsService { /** * 2.2.1任务执行回馈 * * @param rcsReporterTask * @return */ RcsReturn reporterTask(RcsReporterTask rcsReporterTask); } src/main/java/com/zy/service/impl/ApiLogServiceImpl.java
New file @@ -0,0 +1,51 @@ package com.zy.service.impl; import com.baomidou.mybatisplus.service.impl.ServiceImpl; import com.core.common.SnowflakeIdWorker; import com.zy.entity.ApiLog; import com.zy.mapper.ApiLogMapper; import com.zy.service.ApiLogService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.Date; @Slf4j @Service("apiLogService") public class ApiLogServiceImpl extends ServiceImpl<ApiLogMapper, ApiLog> implements ApiLogService { @Autowired private SnowflakeIdWorker snowflakeIdWorker; @Async @Override public void save(String namespace, String url, String appkey, String ip, String request, String response, boolean success) { Date now = new Date(); ApiLog apiLog = new ApiLog( String.valueOf(snowflakeIdWorker.nextId()), // 日志编号 namespace, // 名称空间 url, // 接口地址 appkey, // 平台密钥 String.valueOf(now.getTime()), // 时间戳 ip, // 客户端IP request, // 请求内容 response, null, // 异常内容 success ? 1 : 0, // 结果 1, // 状态 now, // 添加时间 null, // 修改时间 null // 备注 ); if (!this.insert(apiLog)) { log.error("接口调用日志保存失败!"); } } @Override public boolean clearWeekBefore() { return this.baseMapper.clearWeekBefore() > 0; } } src/main/java/com/zy/service/impl/RcsServiceImpl.java
New file @@ -0,0 +1,191 @@ package com.zy.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.zy.core.DevpThread; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.SlaveType; import com.zy.core.model.DevpSlave; import com.zy.core.model.Task; import com.zy.core.model.protocol.StaProtocol; import com.zy.core.properties.SlaveProperties; import com.zy.entity.RcsReporterTask; import com.zy.entity.RcsReturn; import com.zy.entity.WrkDetl; import com.zy.entity.WrkMast; import com.zy.enums.RcsRetMethodEnum; import com.zy.service.ApiLogService; import com.zy.service.RcsService; import com.zy.service.WrkDetlService; import com.zy.service.WrkMastService; import com.zy.utils.HttpHandler; import com.zy.utils.News; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Objects; @Slf4j @Service public class RcsServiceImpl implements RcsService { @Value("${dj.url}") public String DJ_URL; @Resource private WrkMastService wrkMastService; @Resource private WrkDetlService wrkDetlService; @Resource private SlaveProperties slaveProperties; @Resource private ApiLogService apiLogService; /** * 2.2.1任务执行回馈 * 厂家:海量、华晓 * * @param rcsReporterTask * @return */ public RcsReturn reporterTask(RcsReporterTask rcsReporterTask) { RcsReturn rcsReturn = new RcsReturn(); String robotTaskCode = rcsReporterTask.getRobotTaskCode(); String singleRobotCode = rcsReporterTask.getSingleRobotCode(); JSONObject values = rcsReporterTask.getExtra().getJSONObject("values"); String method = values.getString("method"); Date now = new Date(); try { if (singleRobotCode.equals("14") || singleRobotCode.equals("15")) { // 两台CTU库机器人编号 WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("task_no", robotTaskCode)); if (wrkMast != null) { Integer ioType = wrkMast.getIoType(); if (Objects.requireNonNull(RcsRetMethodEnum.getEnum(method)) == RcsRetMethodEnum.TASK_END) { if ((ioType == 101 || ioType == 110 || ioType == 103) && wrkMast.getWrkSts() == 12) { // 给输送线下发命令 for (DevpSlave devp : slaveProperties.getDevp()) { DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId()); Map<Integer, StaProtocol> station = devpThread.getStation(); StaProtocol staProtocol = station.get(wrkMast.getSourceStaNo()); if (staProtocol == null) { continue; } else { staProtocol = staProtocol.clone(); } staProtocol.setWorkNo(wrkMast.getWrkNo()); staProtocol.setStaNo(wrkMast.getStaNo().shortValue()); boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol)); if (result) { News.info("RCS给WCS反馈end,输送线命令下发成功:{}", wrkMast.getWrkNo()); } else { rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage("RCS给WCS反馈end,输送线命令下发失败"); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); return rcsReturn; } } wrkMast.setWrkSts(14L); wrkMast.setCrnEndTime(now); wrkMast.setModiTime(now); wrkMastService.updateById(wrkMast); // 给TMS反馈出库货物信息 List<WrkDetl> wrkDetls = wrkDetlService.selectList(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkMast.getWrkNo())); if (!wrkDetls.isEmpty()) { WrkDetl wrkDetl = wrkDetls.get(0); String orderNo = wrkDetl.getOrderNo(); if (!Cools.isEmpty(orderNo)) { // 构造请求参数 JSONObject jsonObject = new JSONObject(); jsonObject.put("billType",wrkDetl.getThreeCode()); jsonObject.put("orderNo", wrkDetl.getOrderNo()); jsonObject.put("createTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now)); JSONArray jsonArray = new JSONArray(); for (WrkDetl detl : wrkDetls) { JSONObject object = new JSONObject(); object.put("itemNo", detl.getMatnr()); object.put("anfme", detl.getAnfme()); jsonArray.add(object); } jsonObject.put("details", jsonArray); String url = DJ_URL + "api/OutboundOrder/WmsOutFinish"; String request = jsonObject.toJSONString(); String response = ""; boolean success = false; try { response = new HttpHandler.Builder() .setUri(DJ_URL) .setPath("api/OutboundOrder/WmsOutFinish") .setJson(request) .build() .doPost(); JSONObject responseJson = JSON.parseObject(response); if (responseJson.getString("Success").equals("1")) { success = true; log.info("CTU出库反馈end,上报TMS成功,工作号:{},明细:{}", wrkMast.getWrkNo(), request); } else { log.error("CTU出库反馈end,上报TMS失败!,工作号:{},明细:{}", wrkMast.getWrkNo(), request); log.error("出库完成上报TMS失败!url:{};request:{};response:{}", url, request, response); } } catch (Exception e) { log.error("出库完成上报TMS异常,request:{}",request); e.printStackTrace(); } finally { try { // 保存接口日志 apiLogService.save( "出库完成上报TMS", url, null, "127.0.0.1", request, response, success ); } catch (Exception e) { log.error("入库保存接口日志异常", e); } } } } } else { log.error("{}ioType{}不在end反馈处理中", wrkMast.getWrkNo(), ioType); } } } } // 返回RCS rcsReturn.setCode("SUCCESS"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } catch (Exception e) { log.error("RCS反馈任务进度处理异常 - {}", rcsReporterTask, e); rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage("内部处理异常"); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } return rcsReturn; } } src/main/resources/application.yml
@@ -94,7 +94,7 @@ # 输送线1 devp[0]: id: 1 ip: 172.26.11.42 ip: 172.26.11.50 port: 102 rack: 0 slot: 0 @@ -104,96 +104,36 @@ barcode: ${wcs-slave.barcode[0].id} backSta: 103 led: ${wcs-slave.led[0].id} # # 入库口2 # inSta[1]: # staNo: 205 # barcode: ${wcs-slave.barcode[2].id} # led: ${wcs-slave.led[2].id} # # 入库口3 # inSta[2]: # staNo: 203 # barcode: ${wcs-slave.barcode[1].id} # led: ${wcs-slave.led[1].id} # backSta: 204 # 空板入库口1 emptyInSta[0]: staNo: 104 barcode: ${wcs-slave.barcode[0].id} backSta: 103 led: ${wcs-slave.led[0].id} # 空板入库口2 # emptyInSta[1]: # staNo: 205 # barcode: ${wcs-slave.barcode[2].id} # led: ${wcs-slave.led[2].id} # # 空板入库口3 # emptyInSta[2]: # staNo: 203 # barcode: ${wcs-slave.barcode[1].id} # backSta: 204 # led: ${wcs-slave.led[1].id} # 拣料入库口1 pickSta[0]: staNo: 104 barcode: ${wcs-slave.barcode[0].id} backSta: 103 led: ${wcs-slave.led[0].id} # # 拣料入库口2 # pickSta[1]: # staNo: 106 # barcode: ${wcs-slave.barcode[1].id} # backSta: 105 # led: ${wcs-slave.led[2].id} # 出库口1 outSta[0]: staNo: 101 led: ${wcs-slave.led[0].id} # 出库口2 # outSta[1]: # staNo: 205 # led: ${wcs-slave.led[2].id} # # 出库口3 # outSta[2]: # staNo: 202 # led: ${wcs-slave.led[1].id} # 条码扫描仪1 barcode[0]: id: 1 ip: 172.26.11.43 port: 51236 # 条码扫描仪2 # barcode[1]: # id: 2 # ip: 172.26.11.44 # port: 51236 # # 条码扫描仪3 # barcode[2]: # id: 3 # ip: 172.26.11.45 # port: 51236 # LED1 led[0]: id: 1 ip: 192.168.5.104 ip: 127.0.0.1 port: 5005 devpPlcId: ${wcs-slave.devp[0].id} staArr: 202 staArr: 103,104 crnId: 1 # LED2 # led[1]: # id: 2 # ip: 192.168.5.105 # port: 5005 # devpPlcId: ${wcs-slave.devp[0].id} # staArr: 204 # crnId: 1 # # LED3 # led[2]: # id: 3 # ip: 192.168.5.106 # port: 5005 # devpPlcId: ${wcs-slave.devp[0].id} # staArr: 205 # crnId: 1 dj: url: http://172.26.11.2/ src/main/resources/mapper/ApiLogMapper.xml
New file @@ -0,0 +1,32 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.mapper.ApiLogMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.zy.entity.ApiLog"> <id column="id" property="id" /> <result column="uuid" property="uuid" /> <result column="namespace" property="namespace" /> <result column="url" property="url" /> <result column="appkey" property="appkey" /> <result column="timestamp" property="timestamp" /> <result column="client_ip" property="clientIp" /> <result column="request" property="request" /> <result column="response" property="response" /> <result column="err" property="err" /> <result column="result" property="result" /> <result column="status" property="status" /> <result column="create_time" property="createTime" /> <result column="update_time" property="updateTime" /> <result column="memo" property="memo" /> </resultMap> <delete id="clearWeekBefore"> delete from man_api_log where 1=1 and datediff(week,create_time,getdate()) >= 1 and result != 1 </delete> </mapper>