扫描可回用包装开发

tags/yfai-pcn-ext-v2.3
jun 8 months ago
parent 47dee04a69
commit bf49601ad1

@ -192,4 +192,16 @@ public interface IMesProductionDispatchContextStepService {
@ApiOperation(value = "验证工步集死循环执行时是否超过最大执行次数")
Boolean dispatchOverEndlessLoopReadTimes(StationRequestBean reqBean, String maxTimes);
@ApiOperation(value = "获取上下文生产扫/读信息:可回用包装条码")
List<MesEquipVariableCollectContext> getScanRecyclablePackageContext(StationRequestBean reqBean);
@ApiOperation(value = "验证上下文扫/读信息:可回用包装条码是否存在")
Boolean checkScanRecyclablePackageIsExistContext(StationRequestBean reqBean);
@ApiOperation(value = "保存上下文扫/读信息:可回用包装条码", notes = "[JSON]List<MesEquipVariableCollectContext>")
Boolean dispatchScanRecyclablePackageContext(StationRequestBean reqBean, List<MesEquipVariableCollectContext> productSnList);
@ApiOperation(value = "删除上下文扫/读信息:可回用包装条码")
void removeScanRecyclablePackageContext(StationRequestBean reqBean);
}

@ -164,6 +164,8 @@ public class MesRecyclablePackageBindingServiceImpl implements IMesRecyclablePac
checkIsScan(mesRecyclablePackageBindingModel);
//查询包条码信息
MesRecyclablePackage mesRecyclablePackage = mesRecyclablePackageService.checkMesRecyclablePackage(mesRecyclablePackageBindingModel.getOrganizeCode(), mesRecyclablePackageBindingModel.getPackageSn());
//查询包类型
MesRecyclablePackageType packageType = mesRecyclablePackageService.checkMesRecyclablePackageType(mesRecyclablePackage.getOrganizeCode(), mesRecyclablePackage.getPackageTypeCode());
//查询包装零件
List<MesRecyclablePackagePart> packagePartList = mesRecyclablePackageService.checkMesRecyclablePackagePart(mesRecyclablePackageBindingModel.getOrganizeCode(), mesRecyclablePackage.getPackageTypeCode());
//条码信息
@ -173,7 +175,7 @@ public class MesRecyclablePackageBindingServiceImpl implements IMesRecyclablePac
//更新数量
mesRecyclablePackageBinding.setTotalQty(findMesRecyclablePackageBindingDetailByPidCount(mesRecyclablePackageBindingModel.getOrganizeCode(), mesRecyclablePackageBinding.getId()));
//自动关箱
if (getMesRecyclablePackagePart(mesRecyclablePackage, packagePartList, mesProduceSn.getPartNo()).getQty().intValue() <= mesRecyclablePackageBinding.getTotalQty()) {
if (!Objects.isNull(packageType.getCheckPartNoFlag()) && CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == packageType.getCheckPartNoFlag() && getMesRecyclablePackagePart(packagePartList,mesRecyclablePackage.getPackageTypeCode(), mesProduceSn.getPartNo()).getQty().intValue() <= mesRecyclablePackageBinding.getTotalQty()) {
mesRecyclablePackageBinding.setStatus(MesExtEnumUtil.RECYCLABLE_PACKAGE_PACKAGE_BINDING_STATUS.CLOSED.getValue());
}
ConvertBean.serviceModelUpdate(mesRecyclablePackageBinding, mesRecyclablePackageBindingModel.getUserName());
@ -181,10 +183,10 @@ public class MesRecyclablePackageBindingServiceImpl implements IMesRecyclablePac
return mesRecyclablePackageBinding;
}
private MesRecyclablePackagePart getMesRecyclablePackagePart(MesRecyclablePackage mesRecyclablePackage, List<MesRecyclablePackagePart> packagePartList, String partNo) {
private MesRecyclablePackagePart getMesRecyclablePackagePart(List<MesRecyclablePackagePart> packagePartList,String packageTypeCode, String partNo) {
Optional<MesRecyclablePackagePart> packagePart = packagePartList.stream().filter(t -> t.getPartNo().equals(partNo)).findFirst();
if(!packagePart.isPresent()){
MesPcnException.throwMesBusiException("回用包装类型【%s】零件【%s】数据不存在", mesRecyclablePackage.getPackageTypeCode(), partNo);
MesPcnException.throwMesBusiException("回用包装类型【%s】零件【%s】数据不存在", packageTypeCode, partNo);
}
return packagePart.get();
}

@ -40,6 +40,7 @@ public class MesEquipVariableCfgRuleMatchDispatchService implements IMesEquipVar
case PRODUCT_SN:
case WORK_ORDER:
case PRODUCTION_PART_NO:
case RECYCLABLE_PACKAGE:
return matchEquipVariableCfgCollectContext(reqBean, productionProcessContext, variableCategory, collectContextList, "mesEvcRuleMatchBackValueService");
//TODO CASE 数据变量接口逻辑根据变量类别实现策略

@ -0,0 +1,190 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesCellEquipContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesEquipLogDispatchContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesEquipVariableCollectContext;
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.actor.shipping.dispatch.IFsmCommonService;
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.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.CollectionUtils;
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 :
* @Reference :
* @Author : junsheng.li
* @CreateDate 2024/9/11 13:53
* @Modify:
**/
@Slf4j
@Service("mesRecyclablePackageReadStepService")
public class MesRecyclablePackageReadStepService extends BaseStepService {
@Autowired
private IFsmCommonService fsmCommonService;
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
@Autowired
private IMesEquipmentLogExtService equipmentLogExtService;
@Autowired
private IMesEquipVariableCfgRuleMatchDispatchService equipVariableCfgRuleMatchService;
@Override
public void title(StationRequestBean reqBean) {
this.sendMessage(reqBean, new StationResultBean().resultObj(MesPcnExtConstWords.STEP_DISABLE_SCAN), String.format("工步: %s", reqBean.getStepName()), MesPcnEnumUtil.STATION_BUSI_TYPE.STEP_TITLE, MesPcnEnumUtil.STATION_DATA_TYPE.TITLE);
}
@Override
public StepResult init(StationRequestBean reqBean) {
StepResult stepResult = StepResult.getSuccessComplete();
String endlessLoopReadTimes = fsmCommonService.handleFsmWcpcMapDataForDoScan(reqBean).get(MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES);
if (StringUtils.isEmpty(endlessLoopReadTimes))
endlessLoopReadTimes = MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES_DEFAULT;
if (productionDispatchContextStepService.dispatchOverEndlessLoopReadTimes(reqBean, endlessLoopReadTimes)) {
stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, new StationResultBean().isWs(false).restoreDbLog().checkRepeat(),
stepResult.isCompleted(false).msg(String.format("当前读取到设备的可回用包装条码匹配失败超过[%s]次!", endlessLoopReadTimes)),
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
}
//发送工步内容
productionCustomContextStepService.sendStepContextMessage(reqBean);
return stepResult;
}
@Override
public StepResult execute(StationRequestBean reqBean) {
StationResultBean resultBean = new StationResultBean();
StepResult stepResult = StepResult.getSuccessComplete();
//获取工步参数
Optional<Map<String, MesProdRouteOptParam>> stepParamMap = getStepParams(reqBean);
//获取上下文信息
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean, stepParamMap);
//当前工序已存在读取待验证的可回用包装条码信息
if (productionDispatchContextStepService.checkScanRecyclablePackageIsExistContext(reqBean)) return stepResult;
//获取生产过程上下文对象有异常信息 抛出异常
if (!productionProcessContextStepService.getEquipmentVariableCfgList(productionProcessContext).getSuccess())
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
//从上下文的设备数据变量接口逻辑对象集合中取出当前设备信息的逻辑类型对应的接口逻辑对象集合
List<MesEquipmentVariableCfg> equipmentVariableCfgList = productionProcessContext.getEquipVariableCfgListByVct();
//根据变量类别[可回用包装条码]搜集设备数据变量接口逻辑信息
equipmentVariableCfgList = productionProcessContextStepService.collectEquipmentVariableCfgList(equipmentVariableCfgList, MesExtEnumUtil.EQUIP_VARIABLE_CFG_CATEGORY.RECYCLABLE_PACKAGE.getValue());
//当前工位使用的设备
MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip();
//配置错误 抛出异常
if (!productionProcessContextStepService.checkNecessaryEquipmentVariableCfg(productionProcessContext, cellEquipContext, equipmentVariableCfgList, MesExtEnumUtil.EQUIP_VARIABLE_CFG_CATEGORY.RECYCLABLE_PACKAGE.getValue()).getSuccess())
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
//搜集设备数据变量接口逻辑信息中的二级变量
List<String> categoryLevelTwoList = productionProcessContextStepService.collectCategoryLevelTwoList(equipmentVariableCfgList);
//根据变量类型与二级变量获取设备数据变量信息
List<MesEquipmentVariable> 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);
//获取设备LOG采集数据
MesEquipLogDispatchContext equipLogDispatchContext = equipmentLogExtService.getEquipLogDispatchContext(cellEquipContext, equipmentVariableList, equipmentVariableCfgList);
//验证设备通信质量
productionCustomContextStepService.sendEquipQualityMessage(reqBean, cellEquipContext);
if (!equipmentLogExtService.checkEquipQuality(cellEquipContext.getQuality())) {
this.sendMessage(reqBean, new StationResultBean().writeDbLog().checkRepeat(), String.format("设备网络异常!请检查设备的质量状态,读取到设备[%s]的数据变量质量值为[%s],持续监听中...",
cellEquipContext.getEquipmentName(), cellEquipContext.getQuality()), MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, resultBean,
stepResult.isCompleted(false).msg(String.format("设备[%s]网络异常! 持续监听中...", cellEquipContext.getEquipmentName())),
MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, stepParamMap, MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
}
//匹配读取的可回用包装条码的有效性
matchRecyclablePackageValid(reqBean, resultBean, stepParamMap, stepResult, productionProcessContext, cellEquipContext, equipLogDispatchContext);
//根据设备ID,设备数据变量ID集合 修改设备ID分表采集数据的状态
equipmentLogExtService.updateEquipmentLogList(reqBean.getOrganizeCode(), cellEquipContext.getEquipId(), equipLogDispatchContext.getResetEquipVariableIdList());
return stepResult;
}
//匹配读取的可回用包装条码的有效性
private StepResult matchRecyclablePackageValid(StationRequestBean reqBean, StationResultBean resultBean, Optional<Map<String, MesProdRouteOptParam>> stepParamMap, StepResult stepResult, MesProductionProcessContext productionProcessContext, MesCellEquipContext cellEquipContext, MesEquipLogDispatchContext equipLogDispatchContext) {
//未采集到数据
if (!equipLogDispatchContext.getIsCollectValue())
stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult.isCompleted(false).msg(String.format("当前未读取到设备[%s]可回用包装条码,持续监听中...", cellEquipContext.getEquipmentName())),
MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, stepParamMap, MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
//读取的可回用包装条码进行规则匹配
List<MesEquipVariableCollectContext> equipVariableCollectContextList = (List<MesEquipVariableCollectContext>) equipVariableCfgRuleMatchService.matchEquipVariableCfgCollectContext(reqBean, productionProcessContext, MesExtEnumUtil.EQUIP_VARIABLE_CFG_CATEGORY.RECYCLABLE_PACKAGE.getValue(), equipLogDispatchContext.getEquipVariableCfgCollectContextList());
//没有有效的数据
if (CollectionUtils.isEmpty(equipVariableCollectContextList)) {
this.sendMessage(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.READ.getValue()).checkRepeat(),
String.format("当前未读取到设备[%s]有效的可回用包装条码,持续监听中...%s", cellEquipContext.getEquipmentName(), JSONObject.toJSONString(equipLogDispatchContext)), MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, resultBean,
stepResult.isCompleted(false).msg(String.format("当前未读取到设备[%s]有效的可回用包装条码,持续监听中...", cellEquipContext.getEquipmentName())),
MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, stepParamMap, MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
}
this.sendMessage(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.READ.getValue()).checkRepeat(),
String.format("读取到设备[%s]可回用包装条码的详细JSON内容: %s", cellEquipContext.getEquipmentName(), JSONObject.toJSONString(equipLogDispatchContext)), MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
//保存设备当前一轮工序的待验证的可回用包装条码信息
productionDispatchContextStepService.dispatchScanRecyclablePackageContext(reqBean, equipVariableCollectContextList);
//发送工步内容
String scanInfo = equipVariableCollectContextList.stream().filter(Objects::nonNull).map(MesEquipVariableCollectContext::getEquipVariableValue).collect(Collectors.joining(MesPcnExtConstWords.SEMICOLON));
productionCustomContextStepService.sendStepContextMessage(reqBean, scanInfo, MesExtEnumUtil.CELL_MESSAGE_SOURCE.READ);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.READ.getValue()).scanInfo(scanInfo), stepResult, String.format("当前已读取到设备[%s]可回用包装条码信息[%s]!", cellEquipContext.getEquipmentName(), scanInfo));
}
}

@ -430,4 +430,29 @@ public class MesProductionDispatchContextStepService extends BaseStepService imp
return false;
}
@Override
public List<MesEquipVariableCollectContext> getScanRecyclablePackageContext(StationRequestBean reqBean) {
String productSnJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.SCAN_RECYCLABLE_PACKAGE_CONTEXT);
return !StringUtils.isEmpty(productSnJson) ? JSONObject.parseArray(productSnJson, MesEquipVariableCollectContext.class) : null;
}
//验证上下文扫/读信息:可回用包装条码是否存在
@Override
public Boolean checkScanRecyclablePackageIsExistContext(StationRequestBean reqBean) {
String productSnJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.SCAN_RECYCLABLE_PACKAGE_CONTEXT);
return !StringUtils.isEmpty(productSnJson);
}
//保存上下文扫/读信息:可回用包装条码 [JSON]List<MesEquipVariableCollectContext>
@Override
public Boolean dispatchScanRecyclablePackageContext(StationRequestBean reqBean, List<MesEquipVariableCollectContext> productSnList) {
if (CollectionUtils.isEmpty(productSnList)) return false;
return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.SCAN_RECYCLABLE_PACKAGE_CONTEXT, JSONObject.toJSONString(productSnList));
}
@Override
public void removeScanRecyclablePackageContext(StationRequestBean reqBean) {
removeFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.SCAN_RECYCLABLE_PACKAGE_CONTEXT);
}
}

@ -397,6 +397,8 @@ public class MesPcnExtConstWords {
public static final String SCAN_PRODUCT_SN_CONTEXT = "SCAN_PRODUCT_SN_CONTEXT";
// 上下文: 扫/读信息:装配件条码
public static final String SCAN_ASSEMBLY_SN_CONTEXT = "SCAN_ASSEMBLY_SN_CONTEXT";
// 上下文: 扫/读信息:可回用包装条码
public static final String SCAN_RECYCLABLE_PACKAGE_CONTEXT = "SCAN_RECYCLABLE_PACKAGE_CONTEXT";
// 上下文: 产品加工规则数据信息
public static final String PROD_RULE_DATA_CONTEXT = "PROD_RULE_DATA_CONTEXT";
// 上下文: 进料条码数据信息

Loading…
Cancel
Save