package com.zt.life.modules.mainPart.taskReliability.service; import com.alibaba.fastjson.JSONObject; import com.zt.common.service.BaseService; import com.zt.common.servlet.Result; import com.zt.common.utils.UUIDUtil; import com.zt.life.modules.mainPart.basicInfo.dao.ParamDataDao; import com.zt.life.modules.mainPart.basicInfo.dao.XhProductModelDao; import com.zt.life.modules.mainPart.basicInfo.model.ParamData; import com.zt.life.modules.mainPart.basicInfo.model.XhProductModel; import com.zt.life.modules.mainPart.taskReliability.dao.*; import com.zt.life.modules.mainPart.taskReliability.dto.ProductStatusDto; import com.zt.life.modules.mainPart.taskReliability.dto.TaskModelCheckResult; import com.zt.life.modules.mainPart.taskReliability.model.*; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; /** * simulat_assess * * @author zt generator * @since 1.0.0 2024-03-20 */ @Service public class SimulatAssessService extends BaseService { private static final Logger logger = LoggerFactory.getLogger(SimulatAssessService.class); private static final String RELIA_SIM_TASK_TYPE_SIMULATION = "calcreq"; @Value("${spring.redis.host}") private String redisHost; @Value("${spring.redis.port}") private String redisPort; @Value("${data.reliaSimLib.mainPy}") private String reliaSimMain; @Value("${data.reliaSimLib.resultHome}") private String resultHome; @Autowired private RedisTemplate redisTemplate; @Autowired private TaskService taskService; @Autowired private TaskPhaseService taskPhaseService; @Autowired private SimulatAssessTaskPhaseModelService simulatAssessTaskPhaseModelService; @Autowired private TaskPhaseDao taskPhaseDao; @Autowired private TaskPhaseModelDao taskPhaseModelDao; @Autowired private OperatConditModelDao operatConditModelDao; @Autowired private ModelNodeAlgorithmDao modelNodeAlgorithmDao; @Autowired private AlgorithmDao algorithmDao; @Autowired private XhProductModelDao xhProductModelDao; @Autowired private ParamDataDao paramDataDao; /** * 分页查询 * * @param queryFilter * @return */ /* public List page(QueryFilter queryFilter) { return baseDao.getList(queryFilter.getQueryParams()); }*/ /** * 删除 * * @param ids */ public void delete(Long[] ids) { super.deleteLogic(ids); } public Integer getNumById(Long productId, Long taskModelId) { return baseDao.getNumById(productId, taskModelId); } public List getList(Long productId, Long taskModelId) { return baseDao.getList(productId, taskModelId); } public SimulatAssess getParams(Long id, Long taskModelId) { return baseDao.getParams(id, taskModelId); } public List getChildren(Long productId, Long taskId) { return baseDao.getChildren(productId, taskId); } @Transactional(rollbackFor = Exception.class) public Result simulate(SimulatAssess simulatAssess) { Result result = null; // 1. 检查模型完整性 List chkResult = taskService.checkTaskModel(simulatAssess.getProductId(), simulatAssess.getTaskModelId()); if (chkResult.size() > 0) { result = Result.error("模型不完整,请检查模型定义及参数配置。"); return result; } // 2. 组装供算法库仿真的模型xml assembleModelXml(simulatAssess); // 3. 调用算法库,进行仿真计算 result = callReliaSimLib(simulatAssess); return result; } private Result callReliaSimLib(SimulatAssess simulatAssess) { Result result = null; InputStream is = null; BufferedReader br = null; try { setParamToRedis(simulatAssess); Process process = null; String command = "python " + reliaSimMain; command += " -ip " + redisHost + " -port " + redisPort; command += " -taskType " + RELIA_SIM_TASK_TYPE_SIMULATION + " -taskId " + simulatAssess.getId().toString(); logger.info("cmd命令为:" + command); if(System.getProperty("os.name").toLowerCase().indexOf("windows") > -1){ process = Runtime.getRuntime().exec(new String[]{"cmd", "/c", command}); }else if(System.getProperty("os.name").toLowerCase().indexOf("linux") > -1){ process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", command}); }else{ throw new Exception("暂不支持该操作系统,进行启动算法库计算!"); } is = process.getInputStream(); // 以命令行方式调用算法库时,接口约定返回的结果是utf-8编码 br = new BufferedReader(new InputStreamReader(is,"utf-8")); String line = br.readLine(); logger.info("算法库返回结果:" + line); // int exitCode = process.waitFor(); // 异步方式,不等待算法库计算完毕,所以要注释掉该行 if (line != null) { ReliaSimLibResult rtn = JSONObject.parseObject(line, ReliaSimLibResult.class); if ("0".equals(rtn.getCode())) { logger.info("启动算法库成功。"); result = Result.ok(); } else { String errorMsg = rtn.getErrorMsg(); throw new RuntimeException("启动算法库失败: errorMsg=" + errorMsg); } } } catch (Exception e) { logger.error("启动算法库仿真时发生Exception:", e); e.printStackTrace(); result = Result.error(e.getMessage()); } finally { if (is != null) { try { is.close(); } catch (Exception e) { e.printStackTrace(); } } if (br != null) { try { br.close(); } catch (Exception e) { e.printStackTrace(); } } } return result; } private void setParamToRedis(SimulatAssess simulatAssess) { String key = simulatAssess.getId().toString() + RELIA_SIM_TASK_TYPE_SIMULATION; logger.info("redis key:" + key); JSONObject jsonObject = new JSONObject(); jsonObject.put("xmlfile", simulatAssess.getXml()); // 仿真次数 jsonObject.put("simulate_times", simulatAssess.getSimulatFrequency()); // 采样周期 jsonObject.put("timeslice", simulatAssess.getSamplPeriod()/60.0); // 单位统一换算为小时 jsonObject.put("result_home", resultHome); jsonObject.put("seed", 1000); redisTemplate.opsForValue().set(key, jsonObject.toJSONString()); } private void assembleModelXml(SimulatAssess simulatAssess) { Long productId = simulatAssess.getProductId(); List productList = xhProductModelDao.getByShipId(productId); List paramDataList = paramDataDao.getDeviceParams(productId); Long taskId = simulatAssess.getTaskModelId(); Task task = taskService.get(taskId); // 1. 计算各任务阶段的运行时长 List taskPhases = calcTaskPhaseDuration(task); // 2. 计算各工况模型的运行时长 List taskPhaseModelAll = new ArrayList<>(); for (TaskPhase taskPhase : taskPhases) { calcTaskPhaseModelDuration(taskPhase, taskPhaseModelAll); } // 3. 将各工况模型递归拆解为完整的可供算法包仿真计算的模型 try { List failureModels = new ArrayList<>(); List repairModels = new ArrayList<>(); Document document = DocumentHelper.createDocument(); // 添加root节点 Element root = document.addElement("des"); root.addAttribute("name", "General system"); addTasksTag(taskPhaseModelAll, root); addModelsTag(productId, productList, paramDataList, taskPhaseModelAll, root, failureModels, repairModels); addFailureModelsTag(failureModels, root); addRepairModelsTag(repairModels, root); saveSimulatAssessTaskPhaseModel(simulatAssess, task, taskPhases, taskPhaseModelAll); // 输出格式化xml XMLWriter xmlWriter = null; try { OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); StringWriter writer = new StringWriter(); xmlWriter = new XMLWriter(writer, format); xmlWriter.write(document); simulatAssess.setXml(writer.toString()); } finally { if (xmlWriter != null) xmlWriter.close(); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("组装算法库仿真计算用模型XML失败: " + e.getMessage()); } } private void saveSimulatAssessTaskPhaseModel(SimulatAssess simulatAssess, Task task, List taskPhases, List taskPhaseModelAll) { int sort = 1; for (TaskPhaseModel tpm : taskPhaseModelAll) { TaskPhase phase = taskPhases.stream().filter(item -> tpm.getPhaseId().equals(item.getId())).collect(Collectors.toList()).get(0); SimulatAssessTaskPhaseModel satpm = new SimulatAssessTaskPhaseModel(); satpm.setId(UUIDUtil.generateId()); satpm.setFzId(simulatAssess.getId()); satpm.setTaskId(task.getId()); satpm.setTaskName(task.getTaskName()); satpm.setTaskDuration(task.getTaskDuration()); satpm.setPhaseId(tpm.getPhaseId()); satpm.setPhaseName(phase.getPhaseName()); satpm.setPhaseDurationRate(phase.getPhaseDurationRate()); satpm.setPhaseDuration(phase.getPhaseDuration()); satpm.setPhaseConstraint(null); // TODO satpm.setGkId(tpm.getOperatConditId()); satpm.setGkName(tpm.getOperatConditName()); satpm.setGkDurationRate(tpm.getOperatConditDurationRate()); satpm.setGkDuration(tpm.getOperatConditDuration()); satpm.setSort(sort++); simulatAssessTaskPhaseModelService.insert(satpm); } } private void addTasksTag(List taskPhaseModelAll, Element root) { Element tasksTag = root.addElement("tasks"); for (TaskPhaseModel taskPhaseModel : taskPhaseModelAll) { Element taskTag = tasksTag.addElement("task"); taskTag.addAttribute("duration", String.valueOf(taskPhaseModel.getOperatConditDuration())); taskTag.addAttribute("model", taskPhaseModel.getOperatConditId().toString()); } } private void addFailureModelsTag(List failureModels, Element root) { Element ele = null; Element failureModelsTag = root.addElement("failure_models"); for (FailureModel failureModel : failureModels) { Element failureModelTag = failureModelsTag.addElement("failure_model"); failureModelTag.addAttribute("name", failureModel.getId().toString()); failureModelTag.addAttribute("type", failureModel.getType()); switch (failureModel.getType()) { case FailureModel.TYPE_EXP: ele = failureModelTag.addElement("failure-rate"); ele.addAttribute("value", String.valueOf(failureModel.getParam1())); break; case FailureModel.TYPE_BIN: ele = failureModelTag.addElement("reliability"); ele.addAttribute("value", String.valueOf(failureModel.getParam1())); ele = failureModelTag.addElement("n"); ele.addAttribute("value", String.valueOf(failureModel.getParam2())); ele = failureModelTag.addElement("k"); ele.addAttribute("value", String.valueOf(failureModel.getParam3())); break; case FailureModel.TYPE_WBL: ele = failureModelTag.addElement("scale"); ele.addAttribute("value", String.valueOf(failureModel.getParam2())); ele = failureModelTag.addElement("shape"); ele.addAttribute("value", String.valueOf(failureModel.getParam3())); break; case FailureModel.TYPE_FIX: ele = failureModelTag.addElement("unreliability"); ele.addAttribute("value", String.valueOf(failureModel.getParam1())); break; default: break; } } } private void addRepairModelsTag(List repairModels, Element root) { Element ele = null; Element repairModelsTag = root.addElement("repair_models"); for (RepairModel repairModel : repairModels) { Element repairModelTag = repairModelsTag.addElement("repair_model"); repairModelTag.addAttribute("name", repairModel.getId().toString()); repairModelTag.addAttribute("type", repairModel.getType()); switch (repairModel.getType()) { case RepairModel.TYPE_EXP: ele = repairModelTag.addElement("repair-rate"); ele.addAttribute("value", String.valueOf(repairModel.getParam1())); break; case RepairModel.TYPE_WBL: ele = repairModelTag.addElement("scale"); ele.addAttribute("value", String.valueOf(repairModel.getParam2())); ele = repairModelTag.addElement("shape"); ele.addAttribute("value", String.valueOf(repairModel.getParam3())); break; default: break; } } } private void calcTaskPhaseModelDuration(TaskPhase taskPhase, List taskPhaseModelAll) { List taskPhaseModels = taskPhaseModelDao.getListByPhaseId(taskPhase.getId()); double totalRate = taskPhaseModels.stream().mapToDouble(TaskPhaseModel::getOperatConditDurationRate).sum(); double sum = 0.0; for (TaskPhaseModel taskPhaseModel : taskPhaseModels) { double duration = taskPhase.getPhaseDuration() * taskPhaseModel.getOperatConditDurationRate() / totalRate; taskPhaseModel.setOperatConditDuration(duration); sum += duration; taskPhaseModelAll.add(taskPhaseModel); } // 把零头补到最后一个工况模型 taskPhaseModels.get(taskPhaseModels.size()-1).setOperatConditDuration(taskPhase.getPhaseDuration() - sum); } private List calcTaskPhaseDuration(Task task) { List taskPhases = taskPhaseDao.getListByTaskId(task.getId()); double totalRate = taskPhases.stream().mapToDouble(TaskPhase::getPhaseDurationRate).sum(); double sum = 0.0; for (TaskPhase taskPhase : taskPhases) { double duration = task.getTaskDuration() * taskPhase.getPhaseDurationRate() / totalRate; taskPhase.setPhaseDuration(duration); sum += duration; } // 把零头补到最后一个阶段 taskPhases.get(taskPhases.size()-1).setPhaseDuration(task.getTaskDuration() - sum); return taskPhases; } private void addModelsTag(Long productId, List productList, List paramDataList, List taskPhaseModelAll, Element root, List failureModels, List repairModels) { Element modelsTag = root.addElement("models"); for (TaskPhaseModel taskPhaseModel : taskPhaseModelAll) { Element modelTag = modelsTag.addElement("model"); modelTag.addAttribute("name", taskPhaseModel.getOperatConditId().toString()); List gkModelsAssembled = operatConditModelDao.getGKModelAssembled( taskPhaseModel.getOperatConditId()); OperatConditModel gkModelTop = gkModelsAssembled.stream().filter(item -> productId.equals(item.getProductId())).collect(Collectors.toList()).get(0); List modelNodeAndVnodeList = modelNodeAlgorithmDao.getListByModelId(gkModelTop.getModelId()); List algorithmList = algorithmDao.getListByModelId(gkModelTop.getModelId()); // 将模型转换为DOM,添加到model标签 Algorithm endAlgo = algorithmList.stream().filter(item -> "end".equals(item.getAlgorithmType())).collect(Collectors.toList()).get(0); ModelNode computerNode = modelNodeAndVnodeList.stream().filter(item -> endAlgo.getComputerList().equals(item.getId().toString())).collect(Collectors.toList()).get(0); node2DOM(productList, paramDataList, gkModelsAssembled, algorithmList, modelNodeAndVnodeList, computerNode, modelTag, failureModels, repairModels); } } // 递归函数 private void node2DOM(List productList, List paramDataList, List gkModelsAssembled, List algorithmList, List modelNodeAndVnodeList, ModelNode node, Element parent, List failureModels, List repairModels) { if ("node".equals(node.getNodeType())) { Long dataId = node.getDataId(); XhProductModel product = productList.stream().filter(item -> dataId.equals(item.getId())).collect(Collectors.toList()).get(0); if ("3,4,10".equals(product.getProductType())) { // 系统、分系统、虚单元 OperatConditModel gkModel = gkModelsAssembled.stream().filter(item -> dataId.equals(item.getProductId())).collect(Collectors.toList()).get(0); List algorithmListSub = algorithmDao.getListByModelId(gkModel.getModelId()); List modelNodeAndVnodeListSub = modelNodeAlgorithmDao.getListByModelId(gkModel.getModelId()); Algorithm endAlgo = algorithmListSub.stream().filter(item -> "end".equals(item.getAlgorithmType())).collect(Collectors.toList()).get(0); ModelNode computerNode = modelNodeAndVnodeListSub.stream().filter(item -> endAlgo.getComputerList().equals(item.getId().toString())).collect(Collectors.toList()).get(0); node2DOM(productList, paramDataList, gkModelsAssembled, algorithmListSub, modelNodeAndVnodeListSub, computerNode, parent, failureModels, repairModels); } else if ("5".equals(product.getProductType())) { // 设备 ParamData paramData = paramDataList.stream().filter(item -> dataId.equals(item.getProductId())).collect(Collectors.toList()).get(0); Element nodeTag = parent.addElement("node"); nodeTag.addAttribute("name", dataId.toString()); nodeTag.addAttribute("type", "node"); FailureModel failureModel = new FailureModel(); failureModel.setId(UUIDUtil.generateId()); failureModel.setType(FailureModel.TYPE_EXP); failureModel.setParam1(1.0 / paramData.getTaskMtbcfRegulate()); failureModels.add(failureModel); Element failureTag = nodeTag.addElement("failure_model"); failureTag.addAttribute("name", failureModel.getId().toString()); if (1 == paramData.getRepairable()) { RepairModel repairModel = new RepairModel(); repairModel.setId(UUIDUtil.generateId()); repairModel.setType(RepairModel.TYPE_EXP); repairModel.setParam1(1.0 / paramData.getRepairMttcr()); repairModels.add(repairModel); Element repairTag = nodeTag.addElement("repair_model"); repairTag.addAttribute("name", repairModel.getId().toString()); } } } else { // vnode(运算节点) Algorithm algo = algorithmList.stream().filter(item -> node.getId().equals(item.getId())).collect(Collectors.toList()).get(0); Element element = parent.addElement("logic"); element.addAttribute("name", algo.getId().toString()); if ("series".equals(algo.getAlgorithmType())) { element.addAttribute("type", "series"); } else if ("parallel".equals(algo.getAlgorithmType())) { element.addAttribute("type", "parallel"); } else if ("vote".equals(algo.getAlgorithmType())) { element.addAttribute("type", "vote"); element.addAttribute("k", algo.getVoteNum().toString()); } else if ("switch".equals(algo.getAlgorithmType())) { element.addAttribute("type", "standby"); } else if ("bridge".equals(algo.getAlgorithmType())) { element.addAttribute("type", "bridge"); } String[] computerNodeListStr = algo.getComputerList().split(","); for (String nodeStr : computerNodeListStr) { ModelNode md = modelNodeAndVnodeList.stream().filter(item -> nodeStr.equals(item.getId().toString())).collect(Collectors.toList()).get(0); node2DOM(productList, paramDataList, gkModelsAssembled, algorithmList, modelNodeAndVnodeList, md, element, failureModels, repairModels); } } } }