From 09c1d60704a32e670e8996585f13a23b38d6d9a4 Mon Sep 17 00:00:00 2001 From: "jhforever.wang@estsh.com" Date: Fri, 8 Dec 2023 09:43:36 +0800 Subject: [PATCH] jx collect takt data --- .../ISxThirdPartyPlcCollectDataStepService.java | 4 +- .../ext/mes/pcn/api/busi/jx/IJxPlcExtService.java | 12 +++- .../schedulejob/SxThirdPartyPlcCollectDataJob.java | 6 +- .../busi/collect/SxCellTaktDispatchSingleton.java | 26 ++++---- .../busi/collect/SxCellTaktMonitorHandler.java | 69 ++++++++++++++++++---- .../SxThirdPartyPlcCollectCellTaktService.java | 14 ++++- .../SxThirdPartyPlcCollectCellTaktStepService.java | 54 +++++++++++++++++ .../SxThirdPartyPlcCollectReadPlcStepService.java | 42 +++++++++++-- .../SxThirdPartyPlcCollectStepFilterChain.java | 52 +++++++++++++--- .../SxThirdPartyPlcCollectWritePlcStepService.java | 58 ++++++++++++++++++ .../serviceimpl/busi/jx/JxPlcExtService.java | 15 ++++- .../ext/mes/pcn/pojo/util/MesPcnExtConstWords.java | 10 ++++ 12 files changed, 312 insertions(+), 50 deletions(-) create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectCellTaktStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectWritePlcStepService.java diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/ISxThirdPartyPlcCollectDataStepService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/ISxThirdPartyPlcCollectDataStepService.java index 2965798..96d74dd 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/ISxThirdPartyPlcCollectDataStepService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/ISxThirdPartyPlcCollectDataStepService.java @@ -15,11 +15,11 @@ public interface ISxThirdPartyPlcCollectDataStepService { /** * 第三方PLC数据采集定时任务---步骤执行 - * @param objs 参数 + * @param stepResult 参数 * @return 结果 */ @ApiOperation(value = "第三方PLC数据采集定时任务---步骤执行", notes = "第三方PLC数据采集定时任务---步骤执行") @Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = {ImppBusiException.class, Exception.class}) - StepResult exec(Object... objs); + StepResult exec(StepResult stepResult); } diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/jx/IJxPlcExtService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/jx/IJxPlcExtService.java index 0a9094f..933cadd 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/jx/IJxPlcExtService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/jx/IJxPlcExtService.java @@ -14,7 +14,7 @@ public interface IJxPlcExtService { * 获取PLC信息 * @param organizeCode 组织代码 * @param plcCode PLC代码 - * @return 产品条码信息 + * @return PLC信息 */ @ApiOperation(value = "获取PLC信息", notes = "获取PLC信息") MesPlc getPlcDb(String organizeCode, String plcCode); @@ -36,5 +36,15 @@ public interface IJxPlcExtService { @ApiOperation(value = "写入PLC数据", notes = "写入PLC数据") Boolean doWriteOpcParamValue(MesPlc plc, String value); + /** + * 获取PLC信息 + * @param organizeCode 组织代码 + * @param plcCode PLC代码 + * @param key key + * @return PLC信息 + */ + @ApiOperation(value = "获取PLC信息", notes = "获取PLC信息") + MesPlc getPlcData(String organizeCode, String plcCode, String key); + } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/SxThirdPartyPlcCollectDataJob.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/SxThirdPartyPlcCollectDataJob.java index f3ef2d7..2387fb4 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/SxThirdPartyPlcCollectDataJob.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/SxThirdPartyPlcCollectDataJob.java @@ -30,18 +30,20 @@ public class SxThirdPartyPlcCollectDataJob implements Job { if (StringUtils.isEmpty(param)) return; - log.info("第三方PLC数据采集 --- JOB START --- PARAM:{}", param.toString()); + log.info("第三方PLC数据采集 --- JOB --- PARAM:{}", param.toString()); Map paramMap = JSONObject.parseObject(param.toString(), Map.class); if (!paramMap.containsKey(MesPcnExtConstWords.ORGANIZE_CODE) || !paramMap.containsKey(MesPcnExtConstWords.STRATEGY_CLASS)) return; + log.info("工厂{}第三方PLC数据采集 --- JOB START --- PARAM:{}", paramMap.get(MesPcnExtConstWords.ORGANIZE_CODE), param.toString()); + long startTime = System.currentTimeMillis(); ((ISxThirdPartyPlcCollectDataJobService) SpringContextsUtil.getBean(paramMap.get(MesPcnExtConstWords.STRATEGY_CLASS))).doThirdPartyPlcCollectData(paramMap); long endTime = System.currentTimeMillis(); - log.info("第三方PLC数据采集 --- JOB END --- 耗时: {} ms", endTime - startTime); + log.info("工厂{}第三方PLC数据采集 --- JOB END --- 耗时: {} ms", paramMap.get(MesPcnExtConstWords.ORGANIZE_CODE), endTime - startTime); } } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxCellTaktDispatchSingleton.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxCellTaktDispatchSingleton.java index 70b0fee..26ca82e 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxCellTaktDispatchSingleton.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxCellTaktDispatchSingleton.java @@ -1,6 +1,7 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.collect; import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -30,32 +31,32 @@ public class SxCellTaktDispatchSingleton { public static Boolean getIsInit() { return isInit; } public static synchronized void execMonitor(String org, Map cfgMap) { - if (CollectionUtils.isEmpty(cfgMap)) execMonitorRemove(getCellTaktMonitorMapKeyList(org)); + if (CollectionUtils.isEmpty(cfgMap)) execMonitorRemove(org, getCellTaktMonitorMapKeyList(org)); else execMonitorCompareToCfg(org, cfgMap); } - private static void execMonitorRemove(List removeKeyList) { + private static void execMonitorRemove(String org, List removeKeyList) { + log.info("工厂{}第三方PLC数据采集 --- {} STRATEGY EXEC SINGLETON --- MONITOR CLOSED KEY:{} --- START ---", org, MesPcnExtConstWords.COLLECT_CELL_TAKT, CollectionUtils.isEmpty(removeKeyList) ? MesPcnExtConstWords.EMPTY : JSONObject.toJSONString(removeKeyList)); if (!CollectionUtils.isEmpty(removeKeyList)) removeKeyList.stream().forEach(SxCellTaktDispatchSingleton::execMonitorRemove); } private static void execMonitorCompareToCfg(String org, Map cfgMap) { List cellTaktMonitorMapKeyList = getCellTaktMonitorMapKeyList(org); List removeKeyList = CollectionUtils.isEmpty(cellTaktMonitorMapKeyList) ? null : cellTaktMonitorMapKeyList.stream().filter(o -> (!StringUtils.isEmpty(o) && !cfgMap.containsKey(o))).collect(Collectors.toList()); - execMonitorRemove(removeKeyList); + execMonitorRemove(org, removeKeyList); execMonitorCompute(org, cfgMap); } private static List getCellTaktMonitorMapKeyList(String org) { List cellTaktMonitorMapKeyList = CollectionUtils.isEmpty(cellTaktMonitorMap) ? null : new ArrayList<>(cellTaktMonitorMap.keySet()); - return CollectionUtils.isEmpty(cellTaktMonitorMapKeyList) ? null : cellTaktMonitorMapKeyList.stream().filter(o -> (!StringUtils.isEmpty(o) && o.split(MesPcnExtConstWords.COLON)[0].equals(org))).collect(Collectors.toList()); + return CollectionUtils.isEmpty(cellTaktMonitorMapKeyList) ? null : cellTaktMonitorMapKeyList.stream().filter(o -> (!StringUtils.isEmpty(o) && o.split(MesPcnExtConstWords.COLON)[1].equals(org))).collect(Collectors.toList()); } private static void execMonitorRemove(String key) { - cellTaktMonitorMap.computeIfPresent(key, (k, v) -> { - v.cancel(); - cellTaktMonitorMap.remove(key); - return null; - }); + SxCellTaktMonitorHandler handler = cellTaktMonitorMap.get(key); + handler.cancel(); + cellTaktMonitorMap.remove(key); + log.info("工厂{}第三方PLC数据采集 --- {} STRATEGY EXEC SINGLETON --- MONITOR CLOSED KEY:[{}] ---", key.split(MesPcnExtConstWords.COLON)[1], MesPcnExtConstWords.COLLECT_CELL_TAKT, key); } private static void execMonitorCompute(String org, Map cfgMap) { @@ -63,10 +64,9 @@ public class SxCellTaktDispatchSingleton { if (StringUtils.isEmpty(key)) continue; String[] plcCodeArr = cfgMap.get(key).split(MesPcnExtConstWords.COMMA); if (null == plcCodeArr || plcCodeArr.length != 2) continue; - cellTaktMonitorMap.compute(key, (k, v) -> { - if (null == v) v = new SxCellTaktMonitorHandler(org); - return v.plcCodeArr(plcCodeArr); - }); + SxCellTaktMonitorHandler handler = cellTaktMonitorMap.computeIfAbsent(key, o -> new SxCellTaktMonitorHandler(org, key)); + handler.isRetry(plcCodeArr); + log.info("工厂{}第三方PLC数据采集 --- {} STRATEGY EXEC SINGLETON --- MONITOR {} KEY:[{}] ---", org, MesPcnExtConstWords.COLLECT_CELL_TAKT, handler.version() ? "ADD" : "RETRY", key); } } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxCellTaktMonitorHandler.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxCellTaktMonitorHandler.java index b125acb..bab38a9 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxCellTaktMonitorHandler.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxCellTaktMonitorHandler.java @@ -1,11 +1,16 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.collect; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; +import cn.estsh.i3plus.pojo.mes.model.StepResult; import cn.estsh.impp.framework.boot.util.SpringContextsUtil; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import org.springframework.util.StringUtils; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.ExecutorService; /** @@ -13,20 +18,32 @@ import java.util.concurrent.ExecutorService; */ public class SxCellTaktMonitorHandler { - private volatile Boolean isOpen = true; + protected volatile Boolean isOpen = true; - private volatile String plcCode2Flag; + protected volatile Boolean isRetry = false; - private volatile String plcCode2Data; + protected volatile Integer version = 0; - protected String org; + private SxThirdPartyPlcCollectStepFilterChain filterChain; private ExecutorService executorService; private ListenableFuture listenFuture; - public SxCellTaktMonitorHandler(String org) { + private volatile String plcCode2Flag; + + private volatile String plcCode2Data; + + private String org; + + private String key; + + private StepResult stepResult; + + public SxCellTaktMonitorHandler(String org, String key) { this.org = org; + this.key = key; + initStepResult(); executorService = SpringContextsUtil.getBean(ExecutorService.class); ListeningExecutorService listenExecutor = MoreExecutors.listeningDecorator(executorService); listenFuture = listenExecutor.submit(() -> { @@ -35,34 +52,60 @@ public class SxCellTaktMonitorHandler { }); } - public SxCellTaktMonitorHandler plcCodeArr(String[] plcCodeArr) { + private void initStepResult() { + Map dataMap = new HashMap<>(); + dataMap.put(MesPcnExtConstWords.ORGANIZE_CODE, org); + dataMap.put(MesPcnExtConstWords.KEY, key); + dataMap.put(MesPcnExtConstWords.BUSI_CODE, MesPcnExtConstWords.COLLECT_CELL_TAKT); + dataMap.put(MesPcnExtConstWords.WORK_CENTER_CODE, key.split(MesPcnExtConstWords.COLON)[2]); + dataMap.put(MesPcnExtConstWords.WORK_CELL_CODE, key.split(MesPcnExtConstWords.COLON)[3]); + stepResult = StepResult.getSuccessComplete().data(dataMap); + } + + public SxCellTaktMonitorHandler isRetry(String[] plcCodeArr) { + version ++; + if (isRetry) return this; + if (StringUtils.isEmpty(plcCode2Flag) || !plcCode2Flag.equals(plcCodeArr[0])) plcCode2Flag = null; + if (StringUtils.isEmpty(plcCode2Data) || !plcCode2Data.equals(plcCodeArr[1])) plcCode2Data = null; + if (!StringUtils.isEmpty(plcCode2Flag) && !StringUtils.isEmpty(plcCode2Data)) return this; + isRetry = true; this.plcCode2Flag = plcCodeArr[0]; this.plcCode2Data = plcCodeArr[1]; return this; } public void cancel() { - if (null == this.listenFuture) return; isOpen = false; - listenFuture.cancel(true); + if (null != listenFuture) listenFuture.cancel(true); } - private void execMonitor() { + public Boolean version() { return version == 1 ? true : false; } + private void instanceFilterChain() { + filterChain = new SxThirdPartyPlcCollectStepFilterChain(org, key, MesPcnExtConstWords.COLLECT_CELL_TAKT, plcCode2Flag, plcCode2Data); - while (isOpen) { + filterChain.add(new SxThirdPartyPlcCollectReadPlcStepService(plcCode2Flag).targetValue(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr())) + .add(new SxThirdPartyPlcCollectReadPlcStepService(plcCode2Data)) + .add(new SxThirdPartyPlcCollectWritePlcStepService(plcCode2Flag).targetValue(MesPcnExtConstWords.ZERO_STR)) + .add(new SxThirdPartyPlcCollectCellTaktStepService().targetField(plcCode2Data)); - if (StringUtils.isEmpty(plcCode2Flag) || StringUtils.isEmpty(plcCode2Data)) continue; + isRetry = false; + + } - String plcFlag = plcCode2Flag; + private void execMonitor() { - String plcData = plcCode2Data; + while (isOpen) { + if (StringUtils.isEmpty(plcCode2Flag) || StringUtils.isEmpty(plcCode2Data)) continue; + if (isRetry || null == filterChain) instanceFilterChain(); + filterChain.exec(stepResult); } } + } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectCellTaktService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectCellTaktService.java index a5b38d6..7ebe889 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectCellTaktService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectCellTaktService.java @@ -5,6 +5,7 @@ import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.SxWorkCellTaktCollectPlcCfg; import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.SxWorkCellTaktCollectPlcCfgRepository; import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -16,6 +17,7 @@ import java.util.stream.Collectors; /** * 采集工位节拍实现 */ +@Slf4j @Service public class SxThirdPartyPlcCollectCellTaktService implements ISxThirdPartyPlcCollectDataJobService { @@ -27,19 +29,26 @@ public class SxThirdPartyPlcCollectCellTaktService implements ISxThirdPartyPlcCo String organizeCode = paramMap.get(MesPcnExtConstWords.ORGANIZE_CODE); + log.info("工厂{}第三方PLC数据采集 --- {} STRATEGY START --- PARAM:{}", organizeCode, MesPcnExtConstWords.COLLECT_CELL_TAKT, paramMap.toString()); + if (checkOrgIsStopMonitor(organizeCode, paramMap.get(MesPcnExtConstWords.STATUS))) return; Map cfgMap = getWorkCellTaktCollectPlcCfgList(organizeCode); + log.info("工厂{}第三方PLC数据采集 --- {} STRATEGY EXEC --- CFGMAP:{}", organizeCode, MesPcnExtConstWords.COLLECT_CELL_TAKT, cfgMap.toString()); + if (!SxCellTaktDispatchSingleton.getIsInit()) SxCellTaktDispatchSingleton.getInstance(); SxCellTaktDispatchSingleton.execMonitor(organizeCode, cfgMap); + log.info("工厂{}第三方PLC数据采集 --- {} STRATEGY END --- CFGMAP:{}", organizeCode, MesPcnExtConstWords.COLLECT_CELL_TAKT, cfgMap.toString()); + } private Boolean checkOrgIsStopMonitor(String organizeCode, String status) { if (!StringUtils.isEmpty(status) && status.equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr())) return false; if (SxCellTaktDispatchSingleton.getIsInit()) SxCellTaktDispatchSingleton.execMonitor(organizeCode, null); + log.info("工厂{}第三方PLC数据采集 --- {} STRATEGY END --- MONITOR CLOSED COMPLETED ---", organizeCode, MesPcnExtConstWords.COLLECT_CELL_TAKT); return true; } @@ -53,8 +62,9 @@ public class SxThirdPartyPlcCollectCellTaktService implements ISxThirdPartyPlcCo workCellTaktCollectPlcCfgList = CollectionUtils.isEmpty(workCellTaktCollectPlcCfgList) ? null : workCellTaktCollectPlcCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPlcCode()))).distinct().collect(Collectors.collectingAndThen( Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SxWorkCellTaktCollectPlcCfg::getPlcCode))), ArrayList::new)); - return CollectionUtils.isEmpty(workCellTaktCollectPlcCfgList) ? null : - workCellTaktCollectPlcCfgList.stream().filter(o -> null != o).collect(Collectors.toMap(o -> new StringJoiner(MesPcnExtConstWords.COLON).add(organizeCode).add(o.getWorkCenterCode()).add(o.getWorkCellCode()).toString(), SxWorkCellTaktCollectPlcCfg::getPlcCode)); + return CollectionUtils.isEmpty(workCellTaktCollectPlcCfgList) ? new HashMap<>() : + workCellTaktCollectPlcCfgList.stream().filter(o -> null != o).collect(Collectors.toMap(o -> + new StringJoiner(MesPcnExtConstWords.COLON).add(MesPcnExtConstWords.COLLECT_CELL_TAKT).add(organizeCode).add(o.getWorkCenterCode()).add(o.getWorkCellCode()).toString(), SxWorkCellTaktCollectPlcCfg::getPlcCode)); } } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectCellTaktStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectCellTaktStepService.java new file mode 100644 index 0000000..ec8f97d --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectCellTaktStepService.java @@ -0,0 +1,54 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.collect; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyPlcCollectDataStepService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.SxWorkCellTaktCollectRecord; +import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.SxWorkCellTaktCollectRecordRepository; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.platform.common.convert.ConvertBean; +import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; +import cn.estsh.i3plus.pojo.mes.model.StepResult; +import cn.estsh.impp.framework.boot.util.SpringContextsUtil; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; + +/** + * 第三方PLC数据采集定时任务---步骤执行---写节拍 + */ +@Slf4j +public class SxThirdPartyPlcCollectCellTaktStepService implements ISxThirdPartyPlcCollectDataStepService { + + private SxWorkCellTaktCollectRecordRepository workCellTaktCollectRecordRepository; + + protected String targetField; + + public SxThirdPartyPlcCollectCellTaktStepService() { + this.workCellTaktCollectRecordRepository = (SxWorkCellTaktCollectRecordRepository) SpringContextsUtil.getBean("sxWorkCellTaktCollectRecordRepository"); + } + + public SxThirdPartyPlcCollectCellTaktStepService targetField(String targetField) { + this.targetField = targetField; + return this; + } + + @Override + public StepResult exec(StepResult stepResult) { + + String organizeCode = (String) ((Map) stepResult.getData()).get(MesPcnExtConstWords.ORGANIZE_CODE); + String workCenterCode = (String) ((Map) stepResult.getData()).get(MesPcnExtConstWords.WORK_CENTER_CODE); + String workCellCode = (String) ((Map) stepResult.getData()).get(MesPcnExtConstWords.WORK_CELL_CODE); + Object targetValue = ((Map) stepResult.getData()).get(targetField); + + SxWorkCellTaktCollectRecord workCellTaktCollectRecord = new SxWorkCellTaktCollectRecord(); + workCellTaktCollectRecord.setWorkCenterCode(workCenterCode); + workCellTaktCollectRecord.setWorkCellCode(workCellCode); + workCellTaktCollectRecord.setWorkTakt(targetValue.toString()); + workCellTaktCollectRecord.setOrganizeCode(organizeCode); + workCellTaktCollectRecord.setSystemSyncStatus(MesPcnEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue()); + ConvertBean.serviceModelInitialize(workCellTaktCollectRecord, MesPcnExtConstWords.JOB); + workCellTaktCollectRecordRepository.insert(workCellTaktCollectRecord); + + return stepResult; + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectReadPlcStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectReadPlcStepService.java index d15a7e2..a67e84e 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectReadPlcStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectReadPlcStepService.java @@ -1,8 +1,15 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.collect; import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyPlcCollectDataStepService; +import cn.estsh.i3plus.ext.mes.pcn.api.busi.jx.IJxPlcExtService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.pojo.mes.bean.MesPlc; import cn.estsh.i3plus.pojo.mes.model.StepResult; +import cn.estsh.impp.framework.boot.util.SpringContextsUtil; import lombok.extern.slf4j.Slf4j; +import org.springframework.util.StringUtils; + +import java.util.Map; /** * 第三方PLC数据采集定时任务---步骤执行---读PLC @@ -10,17 +17,40 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class SxThirdPartyPlcCollectReadPlcStepService implements ISxThirdPartyPlcCollectDataStepService { - protected String organizeCode; + protected String plcCode; + + protected String targetValue; - public SxThirdPartyPlcCollectReadPlcStepService(String organizeCode) { - this.organizeCode = organizeCode; + private IJxPlcExtService plcExtService; + + public SxThirdPartyPlcCollectReadPlcStepService(String plcCode) { + this.plcCode = plcCode; + this.plcExtService = (IJxPlcExtService) SpringContextsUtil.getBean("jxPlcExtService"); } - @Override - public StepResult exec(Object ... objs) { - return null; + public SxThirdPartyPlcCollectReadPlcStepService targetValue(String targetValue) { + this.targetValue = targetValue; + return this; } + @Override + public StepResult exec(StepResult stepResult) { + + String organizeCode = (String) ((Map) stepResult.getData()).get(MesPcnExtConstWords.ORGANIZE_CODE); + + String key = (String) ((Map) stepResult.getData()).get(MesPcnExtConstWords.KEY); + MesPlc plc = plcExtService.getPlcData(organizeCode, plcCode, key); + + if (null == plc || (StringUtils.isEmpty(plc.getChannel()) || StringUtils.isEmpty(plc.getDevice()) || StringUtils.isEmpty(plc.getTagAddress()))) return stepResult.isCompleted(false).msg(String.format("读取plcCode:%s 配置无效", plcCode)); + + Object value = plcExtService.doReadOpcParamValue(plc); + + ((Map) stepResult.getData()).put(plcCode, value); + + if (StringUtils.isEmpty(value) || (!StringUtils.isEmpty(targetValue) && !targetValue.equals(value.toString()))) return stepResult.isCompleted(false).msg(String.format("读取plcCode:%s 值无效", plcCode)); + + return stepResult; + } } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectStepFilterChain.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectStepFilterChain.java index 4430115..d9c410b 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectStepFilterChain.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectStepFilterChain.java @@ -2,23 +2,34 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.collect; import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyPlcCollectDataStepService; import cn.estsh.i3plus.pojo.mes.model.StepResult; -import lombok.extern.slf4j.Slf4j; +import com.alibaba.fastjson.JSONObject; +import org.jboss.logging.Logger; +import org.springframework.util.StringUtils; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; /** - * 第三方PLC数据采集定时任务---步骤执行---读PLC + * 第三方PLC数据采集定时任务---步骤执行调度 */ -@Slf4j public class SxThirdPartyPlcCollectStepFilterChain implements ISxThirdPartyPlcCollectDataStepService { - protected String organizeCode; + private static final Logger LOGGER = Logger.getLogger(SxThirdPartyPlcCollectStepFilterChain.class); private List stepServiceList = new LinkedList<>(); - public SxThirdPartyPlcCollectStepFilterChain(String organizeCode) { - this.organizeCode = organizeCode; + private String org; + private String key; + private String busiCode; + private String[] clearField; + + public SxThirdPartyPlcCollectStepFilterChain(String org, String key, String busiCode, String... clearField) { + this.org = org; + this.key = key; + this.busiCode = busiCode; + this.clearField = clearField; } public SxThirdPartyPlcCollectStepFilterChain add(ISxThirdPartyPlcCollectDataStepService stepService) { @@ -27,13 +38,36 @@ public class SxThirdPartyPlcCollectStepFilterChain implements ISxThirdPartyPlcCo } @Override - public StepResult exec(Object ... objs) { + public StepResult exec(StepResult stepResult) { + LOGGER.info(String.format("工厂%s第三方PLC数据采集 --- %s STEP EXEC --- key:[%s] START --- stepResult:%s ---", org, busiCode, key, JSONObject.toJSONString(stepResult))); + try { + for (ISxThirdPartyPlcCollectDataStepService stepService : stepServiceList) { + if (null == stepService) continue; + stepService.exec(stepResult); + if (!stepResult.isCompleted()) break; + } - return null; - } + TimeUnit.MILLISECONDS.sleep(2000L); + + } catch (Exception e) { + LOGGER.info(String.format("工厂%s第三方PLC数据采集 --- %s STEP ERROR --- key:[%s] %s --- stepResult:%s --- %s ---", org, busiCode, key, e.toString(), JSONObject.toJSONString(stepResult), "\r\n" + JSONObject.toJSONString(e))); + } + + LOGGER.info(String.format("工厂%s第三方PLC数据采集 --- %s STEP EXEC --- key:[%s] END --- stepResult:%s ---", org, busiCode, key, JSONObject.toJSONString(stepResult))); + return rollBackStepResult(stepResult); + } + + private StepResult rollBackStepResult(StepResult stepResult) { + if (null == clearField) return stepResult; + for (String field : clearField) { + if (StringUtils.isEmpty(field)) continue; + ((Map) stepResult.getData()).remove(field); + } + return stepResult.isCompleted(true); + } } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectWritePlcStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectWritePlcStepService.java new file mode 100644 index 0000000..87dfb9a --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/collect/SxThirdPartyPlcCollectWritePlcStepService.java @@ -0,0 +1,58 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.collect; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyPlcCollectDataStepService; +import cn.estsh.i3plus.ext.mes.pcn.api.busi.jx.IJxPlcExtService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.pojo.mes.bean.MesPlc; +import cn.estsh.i3plus.pojo.mes.model.StepResult; +import cn.estsh.impp.framework.boot.util.SpringContextsUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.StringUtils; + +import java.util.Map; + +/** + * 第三方PLC数据采集定时任务---步骤执行---写PLC + */ +@Slf4j +public class SxThirdPartyPlcCollectWritePlcStepService implements ISxThirdPartyPlcCollectDataStepService { + + protected String plcCode; + + protected String targetValue; + + private IJxPlcExtService plcExtService; + + public SxThirdPartyPlcCollectWritePlcStepService(String plcCode) { + this.plcCode = plcCode; + this.plcExtService = (IJxPlcExtService) SpringContextsUtil.getBean("jxPlcExtService"); + } + + public SxThirdPartyPlcCollectWritePlcStepService targetValue(String targetValue) { + this.targetValue = targetValue; + return this; + } + + @Override + public StepResult exec(StepResult stepResult) { + + if (StringUtils.isEmpty(targetValue)) return stepResult.isCompleted(false).msg(String.format("写入plcCode:%s 参数缺失目标值", plcCode)); + + String organizeCode = (String) ((Map) stepResult.getData()).get(MesPcnExtConstWords.ORGANIZE_CODE); + + String key = (String) ((Map) stepResult.getData()).get(MesPcnExtConstWords.KEY); + + MesPlc plc = plcExtService.getPlcData(organizeCode, plcCode, key); + + if (null == plc || (StringUtils.isEmpty(plc.getChannel()) || StringUtils.isEmpty(plc.getDevice()) || StringUtils.isEmpty(plc.getTagAddress()))) return stepResult.isCompleted(false).msg(String.format("写入plcCode:%s 配置无效", plcCode)); + + Boolean value = plcExtService.doWriteOpcParamValue(plc, targetValue); + + ((Map) stepResult.getData()).put(plcCode, value); + + if (StringUtils.isEmpty(value) || !value) return stepResult.isCompleted(false).msg(String.format("写入plcCode:%s 失败", plcCode)); + + return stepResult; + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/jx/JxPlcExtService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/jx/JxPlcExtService.java index da7e30f..be81250 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/jx/JxPlcExtService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/jx/JxPlcExtService.java @@ -2,12 +2,15 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.jx; import cn.estsh.i3plus.ext.mes.pcn.api.busi.jx.IJxPlcExtService; import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.mes.pcn.serviceimpl.busi.dispatch.cachedispatch.WorkCellDataCacheDispatch; import cn.estsh.i3plus.platform.plugin.opc.iservice.IOpcUAService; import cn.estsh.i3plus.platform.plugin.opc.service.OpcUAService; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; +import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; import cn.estsh.i3plus.pojo.hardswitch.bean.OpcUAParam; import cn.estsh.i3plus.pojo.mes.bean.MesPlc; import cn.estsh.i3plus.pojo.mes.repository.MesPlcRepository; +import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -45,7 +48,6 @@ public class JxPlcExtService implements IJxPlcExtService { opcParam.setNamespaceIndex(plc.getNameSpaceIndex()); opcParam.setTagValueType(plc.getDataType()); Object result = opcService.getOpcParamValue(opcParam); - opcService.disConnection(); return result; } @@ -60,7 +62,16 @@ public class JxPlcExtService implements IJxPlcExtService { opcParam.setTagValueType(plc.getDataType()); opcParam.setTagValue(value); Boolean result = opcService.editOpcParamValue(opcParam); - opcService.disConnection(); return result; } + + @Override + public MesPlc getPlcData(String organizeCode, String plcCode, String key) { + WorkCellDataCacheDispatch dispatch = new WorkCellDataCacheDispatch.builder().key(key).item(plcCode).build().get(); + if (!StringUtils.isEmpty(dispatch.getValue())) return JSONObject.parseObject(dispatch.getValue(), MesPlc.class); + MesPlc plc = getPlcDb(organizeCode, plcCode); + if (null == plc) plc = new MesPlc(); + new WorkCellDataCacheDispatch.builder().key(key).item(plcCode).value(JSONObject.toJSONString(plc)).timeSecond(MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue()).org(organizeCode).build().save(); + return plc; + } } \ No newline at end of file diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java index beb9cfd..af43322 100644 --- a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java @@ -936,6 +936,7 @@ public class MesPcnExtConstWords { public static final String FORCE = "FORCE"; public static final Integer ZERO = 0; + public static final String ZERO_STR = "0"; public static final String THIRD_PARTY_PID = "thirdPartyPid"; @@ -1019,4 +1020,13 @@ public class MesPcnExtConstWords { //回退工单 public static final String BACK_ORDER = "BACK_ORDER"; + //KEY + public static final String KEY = "key"; + + //工位节拍 + public final static String COLLECT_CELL_TAKT = "COLLECT_CELL_TAKT"; + + //业务代码 + public static final String BUSI_CODE = "BUSI_CODE"; + }