diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java new file mode 100644 index 0000000..b9e2b97 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java @@ -0,0 +1,176 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesEquipVariableRwExtService; +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesCellEquipContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; +import cn.estsh.i3plus.pojo.mes.bean.MesEquipmentVariable; +import cn.estsh.i3plus.pojo.mes.bean.MesEquipmentVariableCfg; +import cn.estsh.i3plus.pojo.mes.bean.MesProdRouteOptParam; +import cn.estsh.i3plus.pojo.mes.model.MesEquipVariableRwResult; +import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; +import cn.estsh.i3plus.pojo.mes.model.StationResultBean; +import cn.estsh.i3plus.pojo.mes.model.StepResult; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @Description : 向PLC点位发送自定义指令工步 + * @Reference : + * @Author : logic + * @CreateDate : 2025/6/9 16:58 + * @Modify: + **/ +@Slf4j +@Service("mesSendUserDefinedCmdStepService") +public class MesSendUserDefinedCmdStepService extends BaseStepService { + + @Autowired + private IMesProductionProcessContextStepService productionProcessContextStepService; + + @Autowired + private IMesEquipVariableRwExtService equipVariableRwExtService; + + @Override + public StepResult execute(StationRequestBean reqBean) { + + StepResult stepResult = StepResult.getSuccessComplete(); + + StationResultBean resultBean = new StationResultBean(); + + //获取工步参数 + Optional> stepParamMap = getStepParams(reqBean); + + //获取上下文信息 + MesProductionProcessContext productionProcessContext = + productionProcessContextStepService.dispatchCurCellEquipment(reqBean, stepParamMap); + + //获取生产过程上下文对象有异常信息 抛出异常 + if (!productionProcessContextStepService.getEquipmentVariableCfgList(productionProcessContext).getSuccess()) { + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); + } + + //从上下文的设备数据变量接口逻辑对象集合中取出当前设备信息的逻辑类型对应的接口逻辑对象集合 + List equipmentVariableCfgList = productionProcessContext.getEquipVariableCfgListByVct(); + + //根据变量类别[用户自定义指令]搜集设备数据变量接口逻辑信息 + equipmentVariableCfgList = productionProcessContextStepService.collectEquipmentVariableCfgList( + equipmentVariableCfgList, MesPcnExtConstWords.USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY); + + //当前工位使用的设备 + MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip(); + + //配置错误 抛出异常 + if (!productionProcessContextStepService.checkNecessaryEquipmentVariableCfgAndValue(productionProcessContext, + cellEquipContext, equipmentVariableCfgList, MesPcnExtConstWords.USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY).getSuccess()) { + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); + } + + //搜集设备数据变量接口逻辑信息中的二级变量 + List categoryLevelTwoList = productionProcessContextStepService.collectCategoryLevelTwoList(equipmentVariableCfgList); + + //根据变量类型与二级变量获取设备数据变量信息 + List equipmentVariableList = productionProcessContextStepService.findEquipmentVariableList( + productionProcessContext, MesExtEnumUtil.EQUIP_VARIABLE_TYPE.PRODUCTION.getValue(), categoryLevelTwoList); + + //配置错误 抛出异常 + if (!productionProcessContextStepService.checkIsEmptyEquipmentVariableList(productionProcessContext, + cellEquipContext, equipmentVariableList, MesExtEnumUtil.EQUIP_VARIABLE_TYPE.PRODUCTION, categoryLevelTwoList).getSuccess()) { + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); + } + + //存储生产过程上下文对象 + productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext); + + //发送数据给设备的数据变量 + return execSendInitializationCmd(reqBean, resultBean, stepParamMap, stepResult, cellEquipContext, + equipmentVariableCfgList, equipmentVariableList, + cellEquipContext.getKepwareFlag(equipmentVariableList.get(0).getChannel())); + + } + + private StepResult execSendInitializationCmd(StationRequestBean reqBean, StationResultBean resultBean, + Optional> stepParamMap, + StepResult stepResult, MesCellEquipContext cellEquipContext, + List equipmentVariableCfgList, + List equipmentVariableList, String kepwareFlag) { + + //最大重试次数[工步参数] + Integer maxRetryTimes = getMaxRetryTimes(stepParamMap); + + MesEquipVariableRwResult equipVariableRwResult = null; + + Map> categoryLevelTwoMap = equipmentVariableCfgList.stream().filter( + Objects::nonNull).collect(Collectors.groupingBy(MesEquipmentVariableCfg::getCategoryLevelTwo)); + + for (int i = 1; i <= maxRetryTimes; i ++) { + + //写值 + for (MesEquipmentVariable equipmentVariable : equipmentVariableList) { + + equipVariableRwResult = equipVariableRwExtService.writeVariable( + categoryLevelTwoMap.get(equipmentVariable.getCategoryLevelTwo()).get(0), equipmentVariable, kepwareFlag); + + if (equipVariableRwResult.getIsSuccessed()) { + this.sendMessage(reqBean, new StationResultBean().writeDbLog().checkRepeat(), + String.format("[%s]%s", cellEquipContext.getEquipmentName(), equipVariableRwResult.getMessage()), + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT); + } else { + this.sendMessage(reqBean, new StationResultBean().writeDbLog().checkRepeat(), + String.format("设备[%s]:初始化指令发送失败!原因:%s", cellEquipContext.getEquipmentName(), + JSONObject.toJSONString(equipVariableRwResult)), MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, + MesPcnEnumUtil.STATION_DATA_TYPE.TEXT); + break; + } + } + + if (!equipVariableRwResult.getIsSuccessed() && equipVariableRwResult.getIsNoCfg()) { + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("设备[%s]:初始化指令发送失败!原因:%s", + cellEquipContext.getEquipmentName(), equipVariableRwResult.getMessage())); + } + + if (equipVariableRwResult.getIsSuccessed()) { + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("设备[%s]:初始化指令发送成功!", cellEquipContext.getEquipmentName())); + } + + stepNonCompleteAndSendMsg(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, String.format("设备[%s]:初始化指令发送失败!累计次数[%s]!原因:%s", cellEquipContext.getEquipmentName(), i, equipVariableRwResult.getMessage())); + + //每失败一次 睡眠 + if (i != maxRetryTimes) { + threadSleep(stepParamMap, MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME); + } + + } + + stepSendTaskCompleteAndThrowEx(reqBean, stepResult, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT); + + return stepResult; + + } + + //最大重试次数[工步参数] + private Integer getMaxRetryTimes(Optional> stepParamMap) { + Integer maxRetryTimes = null; + try { + maxRetryTimes = (null != stepParamMap && stepParamMap.isPresent() && + stepParamMap.get().containsKey(MesPcnExtConstWords.MAX_RETRY_TIMES)) ? + Integer.valueOf(stepParamMap.get().get(MesPcnExtConstWords.MAX_RETRY_TIMES).getParamValue()) : null; + } catch (NumberFormatException e) { + } + return !StringUtils.isEmpty(maxRetryTimes) ? maxRetryTimes : MesPcnExtConstWords.MAX_RETRY_TIMES_DEFAULT; + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesShippingCheckCimSeresLastOrderShippingCodeStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesShippingCheckCimSeresLastOrderShippingCodeStepService.java new file mode 100644 index 0000000..7799a77 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesShippingCheckCimSeresLastOrderShippingCodeStepService.java @@ -0,0 +1,89 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService; +import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; +import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; +import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; +import cn.estsh.i3plus.pojo.mes.model.StationKvBean; +import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; +import cn.estsh.i3plus.pojo.mes.model.StationResultBean; +import cn.estsh.i3plus.pojo.mes.model.StepResult; +import cn.estsh.i3plus.pojo.mes.repository.seres.shipping.MesCimSeresLastOrderShippingCodeRepository; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +import cn.estsh.impp.framework.boot.util.SpringContextsUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.List; + +/** + * @Description : 校验当前扫描的发运单是否为“末单” + * @Reference : + * @Author : logic + * @CreateDate : 2025/6/9 16:38 + * @Modify: + **/ +@Slf4j +@Service("mesShippingCheckCimSeresLastOrderShippingCodeStepService") +public class MesShippingCheckCimSeresLastOrderShippingCodeStepService extends BaseStepService { + + @Autowired + private IMesProductionProcessContextStepService productionProcessContextStepService; + + @Autowired + private IMesProductionCustomContextStepService productionCustomContextStepService; + + @Autowired + private MesCimSeresLastOrderShippingCodeRepository mesCimSeresLastOrderShippingCodeRepository; + + @Override + public StepResult execute(StationRequestBean reqBean) { + StationResultBean resultBean = new StationResultBean(); + + //获取上下文信息 + MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean); + + //配置错误 抛出异常 + if (!productionProcessContext.getSuccess()) { + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); + } + + //存储生产过程上下文对象 + productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext); + + //扫描信息置空 + String scanInfo = reqBean.resetScanInfo(reqBean.getScanInfo()); + + //验证发运组信息是否有效 + List resultList = null; + + if (StringUtils.isEmpty(scanInfo)) { + stepSendGuideAndThrowEx(reqBean, + resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), + "[人工模式]请扫描发运单号!"); + } + + //发送工步内容 + productionCustomContextStepService.sendStepContextMessage(reqBean, scanInfo, MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN); + + //判断当前扫描的发运单号是否是“末单” + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(reqBean.getOrganizeCode()); + DdlPreparedPack.getStringEqualPack(scanInfo, "shippingCode", ddlPackBean); + boolean exitByHql = mesCimSeresLastOrderShippingCodeRepository.isExitByHql(ddlPackBean); + if (exitByHql) { + //当前发运单号为“末单”,则调用“向PLC点位发送自定义指令”工步向PLC点位发送用户自定义指令 + return ((IStepService) SpringContextsUtil.getBean("mesSendUserDefinedCmdStepService")).executeInState(reqBean); + }else { + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), null, + String.format("当前扫描信息发运单号[%s]无须发送末单指令!", scanInfo)); + } + + } + +} 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 29aeea5..50695b6 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 @@ -943,4 +943,7 @@ public class MesPcnExtConstWords { public static final String VOLVO_SEQUENCENUMBER = "sequenceNumber"; public static final String VOLVO_RACKID = "rackId"; public static final String VOLVO_POSITION = "position"; + + //向PLC点位发送用户自定义指令的变量类别 + public static final String USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY = "USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY"; }