From 96579a48b3b558f5ce58cffe372b1f563a9e62ce Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期三, 03 九月 2025 17:23:56 +0800
Subject: [PATCH] 1.配方列表和配方参数获取合并在线程中获取,并更新状态到对话框; 2.配方参数获取; 3.Bonder, AOI, 真空烘烤, 冷却烧烤配方参数解释。

---
 SourceCode/Bond/Servo/Servo.vcxproj                           |    2 
 SourceCode/Bond/Servo/CVacuumBake.cpp                         |   95 +++++-
 SourceCode/Bond/Servo/CRobotTask.cpp                          |    2 
 SourceCode/Bond/Servo/RecipeManager.h                         |   19 +
 SourceCode/Bond/Servo/CJobDataS.cpp                           |    4 
 SourceCode/Bond/Servo/CBakeCooling.cpp                        |   88 ++++-
 SourceCode/Bond/Servo/CRecipesManager.cpp                     |   35 -
 SourceCode/Bond/Servo/CBakeCooling.h                          |    1 
 SourceCode/Bond/Servo/CEquipment.cpp                          |   46 ++
 SourceCode/Bond/Servo/CMaster.cpp                             |    4 
 SourceCode/Bond/Servo/CParam.h                                |   38 ++
 SourceCode/Bond/Servo/CBonder.h                               |    1 
 Document/配方参数.xlsx                                            |    0 
 SourceCode/Bond/Servo/CMeasurement.h                          |    1 
 SourceCode/Bond/Servo/CVacuumBake.h                           |    2 
 SourceCode/Bond/Servo/CRecipeList.h                           |    7 
 SourceCode/Bond/Servo/CRecipesManager.h                       |    7 
 SourceCode/Bond/Servo/PageRecipe.cpp                          |  125 +++++++-
 SourceCode/Bond/Servo/CMeasurement.cpp                        |   62 ++-
 SourceCode/Bond/Servo/Servo.vcxproj.filters                   |    2 
 Document/EO2860AVA-101工艺参数.xlsx                               |    0 
 SourceCode/Bond/Servo/CRecipeList.cpp                         |   37 ++
 Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.10.xlsx |    0 
 SourceCode/Bond/Servo/PageRecipe.h                            |    6 
 SourceCode/Bond/Servo/CEquipment.h                            |    7 
 SourceCode/Bond/Servo/CBonder.cpp                             |  123 ++++++++
 SourceCode/Bond/Servo/CParam.cpp                              |  107 +++++++
 27 files changed, 680 insertions(+), 141 deletions(-)

diff --git "a/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260.xlsx" "b/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260.xlsx"
new file mode 100644
index 0000000..ae31ee6
--- /dev/null
+++ "b/Document/EO2860AVA-101\345\267\245\350\211\272\345\217\202\346\225\260.xlsx"
Binary files differ
diff --git a/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.10.xlsx b/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.10.xlsx
new file mode 100644
index 0000000..e969bd2
--- /dev/null
+++ b/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.10.xlsx
Binary files differ
diff --git "a/Document/\351\205\215\346\226\271\345\217\202\346\225\260.xlsx" "b/Document/\351\205\215\346\226\271\345\217\202\346\225\260.xlsx"
new file mode 100644
index 0000000..d0923fa
--- /dev/null
+++ "b/Document/\351\205\215\346\226\271\345\217\202\346\225\260.xlsx"
Binary files differ
diff --git a/SourceCode/Bond/Servo/CBakeCooling.cpp b/SourceCode/Bond/Servo/CBakeCooling.cpp
index 26f70b6..6523764 100644
--- a/SourceCode/Bond/Servo/CBakeCooling.cpp
+++ b/SourceCode/Bond/Servo/CBakeCooling.cpp
@@ -207,33 +207,33 @@
 
 		{
 			// 请求配方参数
-			//CEqWriteStep* pStep = new CEqWriteStep();
-			//pStep->setName(STEP_EQ_RECIPE_PARAMETER_REQ);
-			//pStep->setWriteSignalDev(0x967);
-			//pStep->setDataDev(0x379b);
-			//if (addStep(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pStep) != 0) {
-			//	delete pStep;
-			//}
+			CEqWriteStep* pStep = new CEqWriteStep();
+			pStep->setName(STEP_EQ_RECIPE_PARAMETER_REQ);
+			pStep->setWriteSignalDev(0x967);
+			pStep->setDataDev(0x24fb);
+			if (addStep(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pStep) != 0) {
+				delete pStep;
+			}
 		}
 
 		{
 			// recipe parameter report
-			//CEqReadStep* pStep = new CEqReadStep(0x1aa54, 257 * 2,
-			//	[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
-			//		if (code == ROK && pszData != nullptr && size > 0) {
-			//			// 此处解释配方数据
-			//			short ret = decodeRecipeParameterReport(pszData, size);
-			//			pStep->setReturnCode(ret);
-			//		}
-			//		pStep->setReturnCode(MRLRC_OK);
-			//		return -1;
-			//	});
-			//pStep->setName(STEP_EQ_RECIPE_PARAMETER);
-			//pStep->setWriteSignalDev(0x94c);
-			//pStep->setReturnDev(m_nIndex == 0 ? 0x126c : 0x1bbc);
-			//if (addStep(STEP_ID_RECIPE_PARAMETER_REPORT, pStep) != 0) {
-			//	delete pStep;
-			//}
+			CEqReadStep* pStep = new CEqReadStep(0x12a54, 257 * 2,
+				[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
+					if (code == ROK && pszData != nullptr && size > 0) {
+						// 此处解释配方数据
+						short ret = decodeRecipeParameterReport(pszData, size);
+						pStep->setReturnCode(ret);
+					}
+					pStep->setReturnCode(MRLRC_OK);
+					return -1;
+				});
+			pStep->setName(STEP_EQ_RECIPE_PARAMETER);
+			pStep->setWriteSignalDev(0x94c);
+			pStep->setReturnDev(0x250c);
+			if (addStep(STEP_ID_RECIPE_PARAMETER_REPORT, pStep) != 0) {
+				delete pStep;
+			}
 		}
 
 		// 使用CEqReadStep替换CEqJobEventStep
@@ -422,4 +422,46 @@
 		if (pGlass == nullptr) return false;
 		return pGlass->isProcessed(m_nID, getSlotUnit(slot));
 	}
+
+	int CBakeCooling::parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms)
+	{
+		ASSERT(pszData);
+		if (size < 250) return 0;
+		int i = 0, v;
+
+
+		// 1.A_腔烘烤时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("A_腔烘烤时间", 0, "", v * 0.01f));
+		i += 2;
+
+		// 2.A_腔冷却时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("A_腔冷却时间", 0, "", v * 0.01f));
+		i += 2;
+
+		// 3.B_腔烘烤时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("B_腔烘烤时间", 0, "", v * 0.01f));
+		i += 2;
+
+		// 4.BB_腔冷却时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("B_腔冷却时间", 0, "", v * 0.01f));
+		i += 2;
+
+		// 5.A_烘烤温度设定
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("A_烘烤温度设定", 0, "", v * 0.1f));
+		i += 2;
+
+		// 6.B_烘烤温度设定
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("B_烘烤温度设定", 0, "", v * 0.1f));
+		i += 2;
+
+
+		return (int)parsms.size();
+	}
+
 }
diff --git a/SourceCode/Bond/Servo/CBakeCooling.h b/SourceCode/Bond/Servo/CBakeCooling.h
index f60eab1..2cb07d6 100644
--- a/SourceCode/Bond/Servo/CBakeCooling.h
+++ b/SourceCode/Bond/Servo/CBakeCooling.h
@@ -24,6 +24,7 @@
         virtual int getIndexerOperationModeBaseValue();
         virtual short getSlotUnit(short slotNo) { return slotNo % 2 == 1 ? 0 : 1; };
         virtual bool isSlotProcessed(int slot);
+        virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms);
 	};
 }
 
diff --git a/SourceCode/Bond/Servo/CBonder.cpp b/SourceCode/Bond/Servo/CBonder.cpp
index ef46752..3b49a81 100644
--- a/SourceCode/Bond/Servo/CBonder.cpp
+++ b/SourceCode/Bond/Servo/CBonder.cpp
@@ -351,10 +351,10 @@
 
 		{
 			// FAC Data Report
-			CEqReadStep* pStep = new CEqReadStep(0xA60E, 108 * 2,
+			CEqReadStep* pStep = new CEqReadStep(m_nIndex == 0 ? 0xA60E : 0xE60E, 108 * 2,
 				[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
 					if (code == ROK && pszData != nullptr && size > 0) {
-						decodePanelDataReport((CStep*)pFrom, pszData, size);
+						decodeFacDataReport((CStep*)pFrom, pszData, size);
 					}
 					return -1;
 				});
@@ -522,4 +522,123 @@
 	{
 		return m_nIndex == 0 ? 15000 : 20000;
 	}
+
+	int CBonder::parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms)
+	{
+		ASSERT(pszData);
+		if (size < 250) return 0;
+		int i = 0, v;
+
+
+		// 1.校正对位延时
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("校正对位延时", 0, "", v * 0.01f));
+		i += 2;
+
+		// 2.保压时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("保压时间", 0, "", v * 0.01f));
+		i += 2;
+
+		// 3.腔体破真空延时
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("腔体破真空延时", 0, "", v * 0.01f));
+		i += 2;
+
+		// 4.腔体分子泵启动延时
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("腔体分子泵启动延时", 0, "", v * 0.1f));
+		i += 2;
+
+		// 5.腔体贴附抽真空延时
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("腔体贴附抽真空延时", 0, "", v * 0.1f));
+		i += 2;
+
+		// 6.加热等待延时
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("加热等待延时", 0, "", v * 0.1f));
+		i += 2;
+
+		// 7.气囊压力设定
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("气囊压力设定", 0, "", v * 0.1f));
+		i += 4;
+
+		// 8.气囊加压速率
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("气囊加压速率", 0, "", v * 0.1f));
+		i += 4;
+
+		// 9.气囊泄压速率
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("气囊泄压速率", 0, "", v * 0.1f));
+		i += 4;
+
+		// 10.贴附压力上限
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("贴附压力上限", 0, "", v * 0.1f));
+		i += 4;
+
+		// 11.Z轴转矩速度设定
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("上腔Z轴转矩速度设定", 0, "", v * 0.001f));
+		i += 4;
+
+		// 12.上腔温度设定
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("上腔温度设定", 0, "", v * 0.1f));
+		i += 2;
+
+		// 13.下腔温度设定
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("下腔温度设定", 0, "", v * 0.1f));
+		i += 2;
+
+		// 14.上腔Z轴预贴合位速度
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("上腔Z轴预贴合位速度", 0, "", v * 0.001f));
+		i += 4;
+
+		// 15.上腔Z轴贴附位速度
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("上腔Z轴贴附位速度", 0, "", v * 0.001f));
+		i += 4;
+
+		// 16.上腔Z上腔加热位间距
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("上腔Z上腔加热位间距", 0, "", v * 0.001f));
+		i += 4;
+
+		// 17.上腔贴附位压入量
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("上腔贴附位压入量", 0, "", v * 0.001f));
+		i += 4;
+
+		// 18.上腔Z轴破真空距离
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("上腔Z轴破真空距离", 0, "", v * 0.001f));
+		i += 4;
+
+		// 19.下顶Pin破真空距离
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("下顶Pin破真空距离", 0, "", v * 0.001f));
+		i += 4;
+
+		// 20.下顶Pin加热位间距
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("下顶Pin加热位间距", 0, "", v * 0.001f));
+		i += 4;
+
+		// 21.腔体真空泵真空规设定值
+		parsms.push_back(CParam("腔体真空泵真空规设定值", 0, "", (double)toFloat(&pszData[i])));
+		i += 4;
+
+		// 22.腔体分子泵到达设定值
+		parsms.push_back(CParam("腔体分子泵到达设定值", 0, "", (double)toFloat(&pszData[i])));
+		i += 4;
+
+
+		return (int)parsms.size();
+	}
 }
diff --git a/SourceCode/Bond/Servo/CBonder.h b/SourceCode/Bond/Servo/CBonder.h
index 0746fa5..714b949 100644
--- a/SourceCode/Bond/Servo/CBonder.h
+++ b/SourceCode/Bond/Servo/CBonder.h
@@ -24,6 +24,7 @@
         virtual int onProcessData(CProcessData* pProcessData);
         virtual int onProcessStateChanged(PROCESS_STATE state);
         virtual int getIndexerOperationModeBaseValue();
+        virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms);
 
     public:
         void setIndex(unsigned int index);
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index d7f5698..30cdedb 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -1189,28 +1189,39 @@
 		return 0;
 	}
 
-	int CEquipment::recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo)
+	int CEquipment::recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo, ONSYNCINGSTATECHANGED block)
 	{
-		SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(STEP_EQ_MASTER_RECIPE_LIST_REQ);
+		LOGI("<CEquipment-%s>正在请求单元<%d>主配参数列表", m_strName.c_str(), unitNo);
+		m_recipesManager.setOnSyncingStateChanged(block);
+		if (m_recipesManager.syncing() != 0) {
+			return -2;
+		}
+
+		SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(STEP_EQ_RECIPE_PARAMETER_REQ);
 		if (pStep == nullptr) {
 			return -1;
 		}
 
-		LOGI("<CEquipment-%s>正在请求单元<%d>主配方列表", m_strName.c_str(), unitNo);
-		if (m_recipesManager.syncing() != 0) {
-			return -2;
-		}
-		pStep->writeShort(unitNo, [&, unitNo](int code) -> int {
+		char szBuffer[14 * 2] = {0};
+		int index = 0;
+		memcpy(&szBuffer[index], &masterRecipeId, sizeof(short)); 
+		index += sizeof(short);
+		memcpy(&szBuffer[index], &localRecipeId, sizeof(short));
+		index += sizeof(short);
+		memcpy(&szBuffer[index], &unitNo, sizeof(short));
+
+		pStep->writeDataEx(szBuffer, 14 * 2, [&, unitNo](int code) -> int {
 			if (code == WOK) {
-				LOGI("<CEquipment-%s>请求单元<%d>主配方列表成功,正在等待数据.", m_strName.c_str(), unitNo);
+				LOGI("<CEquipment-%s>请求单元<%d>主配方参数列表成功,正在等待数据.", m_strName.c_str(), unitNo);
 			}
 			else {
 				m_recipesManager.syncFailed();
-				LOGI("<CEquipment-%s>请求单元<%d>主配方列表失败,code:%d", m_strName.c_str(), unitNo, code);
+				LOGI("<CEquipment-%s>请求单元<%d>主配方参数列表失败,code:%d", m_strName.c_str(), unitNo, code);
 			}
 
 			return 0;
-			});
+		});
+
 		return 0;
 	}
 
@@ -1733,7 +1744,7 @@
 		std::string strSvTimeRecord, strSvData;
 		CToolUnits::convertString(&pszData[index], 8 * 2, strSvTimeRecord);
 		index += 128 * 2;
-		CToolUnits::convertString(&pszData[index], 640 * 2, strSvData);
+		CToolUnits::convertString(&pszData[index], 100 * 2, strSvData);
 		index += 256 * 2;
 
 
@@ -2075,4 +2086,17 @@
 
 		return InspResult::NotInspected;
 	}
+
+	float CEquipment::toFloat(const char* pszAddr)
+	{
+		BYTE szBuffer[4];
+		szBuffer[0] = pszAddr[0];
+		szBuffer[1] = pszAddr[1];
+		szBuffer[2] = pszAddr[2];
+		szBuffer[3] = pszAddr[3];
+		float f = 0.0;
+		memcpy(&f, szBuffer, 4);
+
+		return f;
+	}
 }
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/CEquipment.h b/SourceCode/Bond/Servo/CEquipment.h
index e23aa10..d7892e4 100644
--- a/SourceCode/Bond/Servo/CEquipment.h
+++ b/SourceCode/Bond/Servo/CEquipment.h
@@ -35,6 +35,7 @@
 #include "CProcessData.h"
 #include "CPortStatusReport.h"
 #include "CSlot.h"
+#include "CParam.h"
 
 
 namespace SERVO {
@@ -165,7 +166,10 @@
 		// masterRecipeId: 主配方id
 		// localRecipeId: 本地配方id
 		// unitNo: 0:local; Others:unit No
-		int recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo);
+		int recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo, ONSYNCINGSTATECHANGED block);
+
+		// 解析配方参数列表
+		virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms) { return 0;  };
 
 		// 获取指定的Slot
 		CSlot* getSlot(int index);
@@ -254,6 +258,7 @@
 		int decodeJobProcessEndReport(CStep* pStep, const char* pszData, size_t size);
 		BOOL compareJobData(CJobDataB* pJobDataB, CJobDataS* pJobDataS);
 		void setProcessState(PROCESS_STATE state);
+		float toFloat(const char* pszAddr);
 
 	protected:
 		BOOL m_bEnable;
diff --git a/SourceCode/Bond/Servo/CJobDataS.cpp b/SourceCode/Bond/Servo/CJobDataS.cpp
index db1bf0d..71a65fb 100644
--- a/SourceCode/Bond/Servo/CJobDataS.cpp
+++ b/SourceCode/Bond/Servo/CJobDataS.cpp
@@ -457,7 +457,7 @@
 
 	int CJobDataS::serialize(char* pszBuffer, int nBufferSize)
 	{
-		if (nBufferSize < 256 * 2) return -1;
+		if (nBufferSize < JOBDATAS_SIZE) return -1;
 
 		int index = 0;
 		memcpy(&pszBuffer[index], &m_nCassetteSequenceNo, sizeof(short));
@@ -558,7 +558,7 @@
 		memcpy(&pszBuffer[index], &m_nProductJudge, sizeof(short));
 		index += sizeof(short);
 
-		return 256 * 2;
+		return JOBDATAS_SIZE;
 	}
 
 	int CJobDataS::unserialize(const char* pszBuffer, int nBufferSize)
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 259991d..e2beaa0 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -2499,7 +2499,9 @@
 			m_pControlJob = new CControlJob();
 			if (!CControlJob::deserialize(ifs, *m_pControlJob)) return false;
 		}
-
+		else {
+			return false;
+		}
 
 		// 读取 ProcessJob 列表
 		uint32_t count = 0;
diff --git a/SourceCode/Bond/Servo/CMeasurement.cpp b/SourceCode/Bond/Servo/CMeasurement.cpp
index f4b41a4..53ffb9c 100644
--- a/SourceCode/Bond/Servo/CMeasurement.cpp
+++ b/SourceCode/Bond/Servo/CMeasurement.cpp
@@ -207,33 +207,33 @@
 
 		{
 			// 请求配方参数
-			//CEqWriteStep* pStep = new CEqWriteStep();
-			//pStep->setName(STEP_EQ_RECIPE_PARAMETER_REQ);
-			//pStep->setWriteSignalDev(0xf67);
-			//pStep->setDataDev(0x379b);
-			//if (addStep(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pStep) != 0) {
-			//	delete pStep;
-			//}
+			CEqWriteStep* pStep = new CEqWriteStep();
+			pStep->setName(STEP_EQ_RECIPE_PARAMETER_REQ);
+			pStep->setWriteSignalDev(0xf67);
+			pStep->setDataDev(0x379b);
+			if (addStep(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pStep) != 0) {
+				delete pStep;
+			}
 		}
 
 		{
 			// recipe parameter report
-			//CEqReadStep* pStep = new CEqReadStep(0x1aa54, 257 * 2,
-			//	[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
-			//		if (code == ROK && pszData != nullptr && size > 0) {
-			//			// 此处解释配方数据
-			//			short ret = decodeRecipeParameterReport(pszData, size);
-			//			pStep->setReturnCode(ret);
-			//		}
-			//		pStep->setReturnCode(MRLRC_OK);
-			//		return -1;
-			//	});
-			//pStep->setName(STEP_EQ_RECIPE_PARAMETER);
-			//pStep->setWriteSignalDev(0xf4c);
-			//pStep->setReturnDev(m_nIndex == 0 ? 0x126c : 0x1bbc);
-			//if (addStep(STEP_ID_RECIPE_PARAMETER_REPORT, pStep) != 0) {
-			//	delete pStep;
-			//}
+			CEqReadStep* pStep = new CEqReadStep(0x1aa54, 257 * 2,
+				[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
+					if (code == ROK && pszData != nullptr && size > 0) {
+						// 此处解释配方数据
+						short ret = decodeRecipeParameterReport(pszData, size);
+						pStep->setReturnCode(ret);
+					}
+					pStep->setReturnCode(MRLRC_OK);
+					return -1;
+				});
+			pStep->setName(STEP_EQ_RECIPE_PARAMETER);
+			pStep->setWriteSignalDev(0xf4c);
+			pStep->setReturnDev(0x37ac);
+			if (addStep(STEP_ID_RECIPE_PARAMETER_REPORT, pStep) != 0) {
+				delete pStep;
+			}
 		}
 
 		// 使用CEqReadStep替换CEqJobEventStep
@@ -416,4 +416,20 @@
 	{
 		return 35000;
 	}
+
+	int CMeasurement::parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms)
+	{
+		ASSERT(pszData);
+		if (size < 250) return 0;
+		int i = 0, v;
+
+
+		// 1.检测功能启用/禁用
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("检测功能启用/禁用", 0, "", v));
+		i += 2;
+
+
+		return (int)parsms.size();
+	}
 }
diff --git a/SourceCode/Bond/Servo/CMeasurement.h b/SourceCode/Bond/Servo/CMeasurement.h
index 519aa53..9a040ee 100644
--- a/SourceCode/Bond/Servo/CMeasurement.h
+++ b/SourceCode/Bond/Servo/CMeasurement.h
@@ -22,6 +22,7 @@
         virtual void getAttributeVector(CAttributeVector& attrubutes);
         virtual int recvIntent(CPin* pPin, CIntent* pIntent);
         virtual int getIndexerOperationModeBaseValue();
+        virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms);
 	};
 }
 
diff --git a/SourceCode/Bond/Servo/CParam.cpp b/SourceCode/Bond/Servo/CParam.cpp
new file mode 100644
index 0000000..4935b4e
--- /dev/null
+++ b/SourceCode/Bond/Servo/CParam.cpp
@@ -0,0 +1,107 @@
+#include "stdafx.h"
+#include "CParam.h"
+
+
+CParam::CParam()
+{
+	m_nValueType = PVT_INT;
+	m_nValue = 0;
+	m_fValue = 0.0;
+}
+
+CParam::CParam(const char* pszName, const char* pszId, const char* pszUnit, int value)
+{
+	m_nValueType = PVT_INT;
+	m_nValue = value;
+	m_fValue = 0.0;
+	m_strId = pszId;
+	m_strName = pszName;
+	m_strUnit = pszUnit;
+}
+
+CParam::CParam(const char* pszName, const char* pszId, const char* pszUnit, double value)
+{
+	m_nValueType = PVT_DOUBLE;
+	m_nValue = 0;
+	m_fValue = value;
+	m_strId = pszId;
+	m_strName = pszName;
+	m_strUnit = pszUnit;
+}
+
+CParam::~CParam()
+{
+}
+
+std::string& CParam::getName()
+{
+	return m_strName;
+}
+
+std::string& CParam::getId()
+{
+	return m_strId;
+}
+
+std::string& CParam::getUnit()
+{
+	return m_strUnit;
+}
+
+int CParam::getValueType()
+{
+	return m_nValueType;
+}
+
+int CParam::getIntValue()
+{
+	return m_nValue;
+}
+
+void CParam::setIntValue(int value)
+{
+	m_nValue = value;
+}
+
+double CParam::getDoubleValue()
+{
+	return m_fValue;
+}
+
+void CParam::setDoubleValue(double value)
+{
+	m_fValue = value;
+}
+
+void CParam::Serialize(CArchive& ar)
+{
+	if (ar.IsStoring())
+	{
+		WriteString(ar, m_strName);
+		WriteString(ar, m_strUnit);
+		ar << m_nValueType;
+		ar << m_nValue;
+		ar << m_fValue;
+	}
+	else
+	{
+		ReadString(ar, m_strName);
+		ReadString(ar, m_strUnit);
+		ar >> m_nValueType;
+		ar >> m_nValue;
+		ar >> m_fValue;
+	}
+}
+
+void CParam::ReadString(CArchive& ar, std::string& string)
+{
+	CString strTemp;
+	ar >> strTemp;
+	string = (LPTSTR)(LPCTSTR)strTemp;
+}
+
+void CParam::WriteString(CArchive& ar, std::string& string)
+{
+	CString strTemp = string.c_str();
+	ar << strTemp;
+}
diff --git a/SourceCode/Bond/Servo/CParam.h b/SourceCode/Bond/Servo/CParam.h
new file mode 100644
index 0000000..f8562a1
--- /dev/null
+++ b/SourceCode/Bond/Servo/CParam.h
@@ -0,0 +1,38 @@
+#pragma once
+#include <string>
+
+#define PVT_INT		0
+#define PVT_DOUBLE	1
+
+class CParam
+{
+public:
+	CParam();
+	CParam(const char* pszName, const char* pszId, const char* pszUnit, int value);
+	CParam(const char* pszName, const char* pszId, const char* pszUnit, double value);
+	~CParam();
+
+public:
+	std::string& getId();
+	std::string& getName();
+	std::string& getUnit();
+	int getValueType();
+	int getIntValue();
+	void setIntValue(int value);
+	double getDoubleValue();
+	void setDoubleValue(double value);
+	void Serialize(CArchive& ar);
+
+private:
+	void ReadString(CArchive& ar, std::string& string);
+	void WriteString(CArchive& ar, std::string& string);
+
+private:
+	int m_nValueType;
+	std::string m_strId;
+	std::string m_strName;
+	std::string m_strUnit;
+	int m_nValue;
+	double m_fValue;
+};
+
diff --git a/SourceCode/Bond/Servo/CRecipeList.cpp b/SourceCode/Bond/Servo/CRecipeList.cpp
index 01eec82..5f1fbd1 100644
--- a/SourceCode/Bond/Servo/CRecipeList.cpp
+++ b/SourceCode/Bond/Servo/CRecipeList.cpp
@@ -77,10 +77,47 @@
 		return m_ids;
 	}
 
+	std::unordered_map<short, std::vector<uint8_t>>& CRecipeList::getParamsRawData()
+	{
+		return m_paramsRawData;
+	}
+
 	void CRecipeList::reset()
 	{
 		m_nToatlGroupCount = 0;
 		m_nCurrentGroupCount = 0;
 		m_ids.clear();
+		m_paramsRawData.clear();
 	}
+
+	int CRecipeList::addParamsPacket(int totalCount, int totalGroup, int currentGroup,
+		short unitId, short recipeId,
+		const char* pszData, size_t size)
+	{
+		if (m_nToatlGroupCount == 0) m_nToatlGroupCount = totalGroup;
+		if (m_nToatlGroupCount != totalGroup) {
+			reset();
+			return MRLRC_GROUP_COUNT_NG;
+		}
+		if (currentGroup == 0) {
+			reset();
+		}
+		if (m_nCurrentGroupCount + 1 > currentGroup) {
+			return MRLRC_DUPLICATION_GROUP_COUNT_NG;
+		}
+		if (m_nCurrentGroupCount + 1 < currentGroup) {
+			return ORDER_BY_GROUP_COUNT_NG;
+		}
+		m_nCurrentGroupCount++;
+
+		m_paramsRawData[recipeId].insert(m_paramsRawData[recipeId].end(), (uint8_t*)(pszData), (uint8_t*)(pszData) + size);
+		if (m_nCurrentGroupCount == m_nToatlGroupCount) {
+			// 解释数据就交给应用层吧
+			return MRLRC_CURRENT_RECIPE_COMPLETE;
+		}
+
+
+		return MRLRC_CONTINUE;
+	}
+
 }
diff --git a/SourceCode/Bond/Servo/CRecipeList.h b/SourceCode/Bond/Servo/CRecipeList.h
index 74e89c3..7038c70 100644
--- a/SourceCode/Bond/Servo/CRecipeList.h
+++ b/SourceCode/Bond/Servo/CRecipeList.h
@@ -15,13 +15,20 @@
 		int addRecipePacket(int totalCount,int totalGroup, int currentGroup, const char* pszData, size_t size);
 		int addRecipe(int index, short id);
 		std::map<int, short>& getIds();
+		std::unordered_map<short, std::vector<uint8_t>>& getParamsRawData();
 		void reset();
+
+		// 添加参数包
+		int addParamsPacket(int totalCount, int totalGroup, int currentGroup,
+			short unitId, short recipeId,
+			const char* pszData, size_t size);
 
 	private:
 		int m_nUnitNo;
 		int m_nToatlGroupCount;
 		int m_nCurrentGroupCount;
 		std::map<int, short> m_ids;
+		std::unordered_map<short, std::vector<uint8_t>> m_paramsRawData;
 	};
 }
 
diff --git a/SourceCode/Bond/Servo/CRecipesManager.cpp b/SourceCode/Bond/Servo/CRecipesManager.cpp
index 354aaac..48ba9d1 100644
--- a/SourceCode/Bond/Servo/CRecipesManager.cpp
+++ b/SourceCode/Bond/Servo/CRecipesManager.cpp
@@ -169,7 +169,7 @@
 				}
 				m_mapRecipes = m_mapRecipesTemp;
 				m_mapRecipesTemp.clear();
-				m_nSyncStatus = SS_COMPLETE;
+				m_nSyncStatus = SS_LIST_COMPLETE;
 				unlock();
 
 				if (m_onSyncingStateChanged != nullptr) {
@@ -230,17 +230,14 @@
 
 
 
-		// 找到对应CRecipeList, 找不到则新建
-		/*
+		// 找到对应CRecipeList, 找不到则返回NG
 		lock();
 		CRecipeList* pRecipeList = getRecipeListFromTemp(unitNo);
 		if (pRecipeList == nullptr) {
-			pRecipeList = new CRecipeList(unitNo);
-			m_mapRecipesTemp[unitNo] = pRecipeList;
+			unlock();
+			return MRLRC_NG;
 		}
 		unlock();
-		ASSERT(pRecipeList);
-		*/
 
 		/*
 		 1: Create
@@ -248,7 +245,6 @@
 		 3: Delete
 		 4: Request from EAS
 		 */
-		/*
 		if (reportType == RT_CREATE) {
 
 		}
@@ -259,26 +255,19 @@
 
 		}
 		else if (reportType == RT_REQUEST_FROM_EAS) {
-			int nRet = pRecipeList->addRecipePacket(toatlGroupCount, currentGroupCount, pszIdsData, 250 * 2);
+			int nRet = pRecipeList->addParamsPacket(totalParameterCount, toatlGroupCount, currentGroupCount,
+				unitNo, localRecipeId, 
+				pszParameterData, 250 * 2);
 			if (MRLRC_CURRENT_RECIPE_COMPLETE == nRet) {
 				lock();
-				if (m_nTotalMasterRecipeCount == m_mapRecipesTemp.size()) {
-					for (auto item : m_mapRecipes) {
-						delete item.second;
-					}
-					m_mapRecipes = m_mapRecipesTemp;
-					m_mapRecipesTemp.clear();
-					m_nSyncStatus = SS_COMPLETE;
-					unlock();
-					return MRLRC_OK;
-				}
+				m_nSyncStatus = SS_PARAMS_COMPLETE;
 				unlock();
+				return MRLRC_OK;
 			}
-			else if (MRLRC_CONTINUE == nRet) {
-				return MRLRC_CONTINUE;
-			}
+
+			return nRet;
 		}
-		*/
+
 
 		return MRLRC_OK;
 	}
diff --git a/SourceCode/Bond/Servo/CRecipesManager.h b/SourceCode/Bond/Servo/CRecipesManager.h
index 388fe4e..450d2dd 100644
--- a/SourceCode/Bond/Servo/CRecipesManager.h
+++ b/SourceCode/Bond/Servo/CRecipesManager.h
@@ -6,9 +6,10 @@
 
 #define SS_NONE					0
 #define SS_SYNCING				1
-#define SS_COMPLETE				2
-#define SS_TIMEOUT				3
-#define SS_FAILED				4
+#define SS_LIST_COMPLETE		2
+#define SS_PARAMS_COMPLETE		3
+#define SS_TIMEOUT				4
+#define SS_FAILED				5
 
 namespace SERVO {
 	typedef std::function<void(int state)> ONSYNCINGSTATECHANGED;
diff --git a/SourceCode/Bond/Servo/CRobotTask.cpp b/SourceCode/Bond/Servo/CRobotTask.cpp
index 1c9f61d..1b4a1aa 100644
--- a/SourceCode/Bond/Servo/CRobotTask.cpp
+++ b/SourceCode/Bond/Servo/CRobotTask.cpp
@@ -220,7 +220,7 @@
 					LOGI(_T("RobotTask已下发到EFEM"));
 				}
 				else {
-					LOGI(_T("RobotTask已下发失败"));
+					LOGI(_T("RobotTask下发失败"));
 				}
 
 				return 0;
diff --git a/SourceCode/Bond/Servo/CVacuumBake.cpp b/SourceCode/Bond/Servo/CVacuumBake.cpp
index dae4069..e409204 100644
--- a/SourceCode/Bond/Servo/CVacuumBake.cpp
+++ b/SourceCode/Bond/Servo/CVacuumBake.cpp
@@ -207,33 +207,33 @@
 
 		{
 			// 请求配方参数
-			//CEqWriteStep* pStep = new CEqWriteStep();
-			//pStep->setName(STEP_EQ_RECIPE_PARAMETER_REQ);
-			//pStep->setWriteSignalDev(0xc67);
-			//pStep->setDataDev(0x379b);
-			//if (addStep(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pStep) != 0) {
-			//	delete pStep;
-			//}
+			CEqWriteStep* pStep = new CEqWriteStep();
+			pStep->setName(STEP_EQ_RECIPE_PARAMETER_REQ);
+			pStep->setWriteSignalDev(0xc67);
+			pStep->setDataDev(0x2e4b);
+			if (addStep(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pStep) != 0) {
+				delete pStep;
+			}
 		}
 
 		{
 			// recipe parameter report
-			//CEqReadStep* pStep = new CEqReadStep(0x1aa54, 257 * 2,
-			//	[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
-			//		if (code == ROK && pszData != nullptr && size > 0) {
-			//			// 此处解释配方数据
-			//			short ret = decodeRecipeParameterReport(pszData, size);
-			//			pStep->setReturnCode(ret);
-			//		}
-			//		pStep->setReturnCode(MRLRC_OK);
-			//		return -1;
-			//	});
-			//pStep->setName(STEP_EQ_RECIPE_PARAMETER);
-			//pStep->setWriteSignalDev(0xc4c);
-			//pStep->setReturnDev(m_nIndex == 0 ? 0x126c : 0x1bbc);
-			//if (addStep(STEP_ID_RECIPE_PARAMETER_REPORT, pStep) != 0) {
-			//	delete pStep;
-			//}
+			CEqReadStep* pStep = new CEqReadStep(0x16a54, 257 * 2,
+				[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
+					if (code == ROK && pszData != nullptr && size > 0) {
+						// 此处解释配方数据
+						short ret = decodeRecipeParameterReport(pszData, size);
+						pStep->setReturnCode(ret);
+					}
+					pStep->setReturnCode(MRLRC_OK);
+					return -1;
+				});
+			pStep->setName(STEP_EQ_RECIPE_PARAMETER);
+			pStep->setWriteSignalDev(0xc4c);
+			pStep->setReturnDev(0x2ec);
+			if (addStep(STEP_ID_RECIPE_PARAMETER_REPORT, pStep) != 0) {
+				delete pStep;
+			}
 		}
 
 		// 使用CEqReadStep替换CEqJobEventStep
@@ -409,4 +409,53 @@
 	{
 		return 30000;
 	}
+
+	int CVacuumBake::parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms)
+	{
+		ASSERT(pszData);
+		if (size < 250) return 0;
+		int i = 0, v;
+
+
+		// 1.A_腔加热时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("A_腔加热时间", 0, "", v * 0.1f));
+		i += 2;
+
+		// 2.B_腔加热时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("B_腔加热时间", 0, "", v * 0.1f));
+		i += 2;
+
+		// 3.A_腔破真空时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("A_腔破真空时间", 0, "", v * 0.01f));
+		i += 2;
+
+		// 4.B_腔破真空时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		parsms.push_back(CParam("B_腔破真空时间", 0, "", v * 0.01f));
+		i += 2;
+
+		// 5.A_腔真空到达值
+		parsms.push_back(CParam("A_腔真空到达值", 0, "", (double)toFloat(&pszData[i])));
+		i += 4;
+
+		// 6.B_腔真空到达值
+		parsms.push_back(CParam("B_腔真空到达值", 0, "", (double)toFloat(&pszData[i])));
+		i += 4;
+
+		// 7.A_腔温控表主控温度设定
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("A_腔温控表主控温度设定", 0, "", v * 0.1f));
+		i += 4;
+
+		// 8.B_腔温控表主控温度设定
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		parsms.push_back(CParam("B_腔温控表主控温度设定", 0, "", v * 0.1f));
+		i += 4;
+
+
+		return (int)parsms.size();
+	}
 }
diff --git a/SourceCode/Bond/Servo/CVacuumBake.h b/SourceCode/Bond/Servo/CVacuumBake.h
index 2663f59..9a49637 100644
--- a/SourceCode/Bond/Servo/CVacuumBake.h
+++ b/SourceCode/Bond/Servo/CVacuumBake.h
@@ -22,7 +22,7 @@
         virtual void getAttributeVector(CAttributeVector& attrubutes);
         virtual int recvIntent(CPin* pPin, CIntent* pIntent);
         virtual int getIndexerOperationModeBaseValue();
-
+        virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms);
 	};
 }
 
diff --git a/SourceCode/Bond/Servo/PageRecipe.cpp b/SourceCode/Bond/Servo/PageRecipe.cpp
index 9d9d83c..3cadbe0 100644
--- a/SourceCode/Bond/Servo/PageRecipe.cpp
+++ b/SourceCode/Bond/Servo/PageRecipe.cpp
@@ -5,8 +5,8 @@
 #include "Servo.h"
 #include "afxdialogex.h"
 #include "PageRecipe.h"
-#include "MsgDlg.h"
 #include "RecipeDeviceBindDlg.h"
+
 
 // CPageRecipe 瀵硅瘽妗�
 
@@ -486,32 +486,11 @@
 		FillDataToListCtrl(vecData);
 	}
 	else {
-		// enable port
-		CMsgDlg msgDlg("璇风瓑寰�", "姝e湪鑾峰彇閰嶆柟...");
-		pEq->masterRecipeListRequest(0, [&, pEq](int status) -> void {
-			if (status == SS_FAILED || status == SS_TIMEOUT) {
-				CString strMsg;
-				strMsg.Format(status == SS_FAILED ? _T("鑾峰彇閰嶆柟澶辫触锛�") : _T("鑾峰彇閰嶆柟瓒呮椂锛�"));
-				msgDlg.DelayClose(3000);
-				msgDlg.SetIcon(MSG_BOX_ERROR);
-				msgDlg.SetTitle(_T("鎿嶄綔澶辫触"));
-				msgDlg.SetMessage((LPTSTR)(LPCTSTR)strMsg);
-				msgDlg.SetMarquee(FALSE, 0);
-				msgDlg.SetCompleteCode(-1);
-			}
-			else if (status == SS_COMPLETE) {
-				CString strMsg;
-				strMsg.Format(_T("鑾峰彇閰嶆柟瀹屾垚锛�"));
-				msgDlg.DelayClose(3000);
-				msgDlg.SetIcon(MSG_BOX_SUCCEED);
-				msgDlg.SetTitle(_T("鎿嶄綔鎴愬姛"));
-				msgDlg.SetMessage((LPTSTR)(LPCTSTR)strMsg);
-				msgDlg.SetMarquee(FALSE, 0);
-				msgDlg.SetCompleteCode(0);
-				SERVO::CRecipeList* pRecipeList = pEq->getRecipeList(0);
-				FillRecipeListToListCtrl(pRecipeList);
-			}
-		});
+		// 鑾峰彇閰嶆柟鍒楄〃
+		CMsgDlg msgDlg("璇风瓑寰�", "姝e湪鑾峰彇閰嶆柟鍒楄〃...");
+		msgDlg.SetData((DWORD_PTR)this);
+		msgDlg.SetDataEx((DWORD_PTR)pEq);
+		msgDlg.BeginThread(SyncThreadFunction);
 		msgDlg.DoModal();
 	}
 }
@@ -556,3 +535,95 @@
 		FillRecipeListToListCtrl(pRecipeList);
 	}
 }
+
+UINT CPageRecipe::SyncThreadFunction(LPVOID lpvData)
+{
+	CMsgDlg* pMsgDlg = (CMsgDlg*)lpvData;
+	CPageRecipe* pPageRecipe = (CPageRecipe*)pMsgDlg->GetData();
+	return pPageRecipe->SyncThreadFunctionInner(pMsgDlg);
+}
+
+UINT CPageRecipe::SyncThreadFunctionInner(CMsgDlg* pMsgDlg)
+{
+	SERVO::CEquipment* pEq = (SERVO::CEquipment*)pMsgDlg->GetDataEx();
+	HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+	int nStep = 0;
+	pEq->masterRecipeListRequest(0, [&, pEq, pMsgDlg, hEvent](int status) -> void {
+		Sleep(300);
+		if (status == SS_FAILED || status == SS_TIMEOUT) {
+			CString strMsg;
+			strMsg.Format(status == SS_FAILED ? _T("鑾峰彇閰嶆柟鍒楄〃澶辫触锛�") : _T("鑾峰彇閰嶆柟鍒楄〃瓒呮椂锛�"));
+			pMsgDlg->SetIcon(MSG_BOX_ERROR);
+			pMsgDlg->SetTitle(_T("鎿嶄綔澶辫触"));
+			pMsgDlg->SetMessage((LPTSTR)(LPCTSTR)strMsg);
+			SetEvent(hEvent);
+		}
+		else if (status == SS_LIST_COMPLETE) {
+			CString strMsg;
+			strMsg.Format(_T("鑾峰彇閰嶆柟鍒楄〃瀹屾垚锛�"));
+			pMsgDlg->SetTitle(_T("鎿嶄綔鎴愬姛"));
+			pMsgDlg->SetMessage((LPTSTR)(LPCTSTR)strMsg);
+			SERVO::CRecipeList* pRecipeList = pEq->getRecipeList(0);
+			if (pRecipeList != nullptr && !pRecipeList->getIds().empty()) {
+				nStep = 1;
+			}
+			SetEvent(hEvent);
+		}
+	});
+	::WaitForSingleObject(hEvent, INFINITE);
+	if (nStep != 1) {
+		pMsgDlg->SetIcon(MSG_BOX_SUCCEED);
+		pMsgDlg->SetMarquee(FALSE, 0);
+		pMsgDlg->SetCompleteCode(-1);
+		pMsgDlg->DelayClose(3000);
+	}
+	ResetEvent(hEvent);
+
+
+	// 鍙傛暟鍒楄〃
+	if (nStep == 1) {
+		SERVO::CRecipeList* pRecipeList = pEq->getRecipeList(0);
+		ASSERT(pRecipeList);
+		auto& ids = pRecipeList->getIds();
+		pMsgDlg->SetTitle(_T("姝e湪鑾峰彇鍙傛暟"));
+		for (auto item : ids) {
+			CString strMsg;
+			strMsg.Format(_T("姝e湪鑾峰彇閰嶆柟 %d 鍙傛暟..."), item.second);
+			pMsgDlg->SetMessage((LPTSTR)(LPCTSTR)strMsg);
+			pEq->recipeParameterRequest(0, item.second, 0, [&, pEq, pMsgDlg](int status) -> void {
+				Sleep(500);
+				if (status == SS_FAILED || status == SS_TIMEOUT) {
+					CString strMsg;
+					strMsg.Format(status == SS_FAILED ? _T("鑾峰彇閰嶆柟 %d 鍙傛暟澶辫触锛�") : _T("鑾峰彇閰嶆柟 %d 鍙傛暟瓒呮椂锛�"), item.second);
+					pMsgDlg->SetMessage((LPTSTR)(LPCTSTR)strMsg);
+
+					Sleep(300);
+					SetEvent(hEvent);
+				}
+				else if (status == SS_PARAMS_COMPLETE) {
+					CString strMsg;
+					strMsg.Format(_T("鑾峰彇閰嶆柟 %d 鍙傛暟瀹屾垚锛�"), item.second);
+					pMsgDlg->SetMessage((LPTSTR)(LPCTSTR)strMsg);
+
+					Sleep(300);
+					SetEvent(hEvent);
+				}
+				});
+			::WaitForSingleObject(hEvent, INFINITE);
+			ResetEvent(hEvent);
+		}
+		
+		pMsgDlg->SetIcon(MSG_BOX_SUCCEED);
+		pMsgDlg->SetTitle(_T("鎿嶄綔瀹屾垚"));
+		pMsgDlg->SetCompleteCode(0);
+		pMsgDlg->SetMarquee(FALSE, 0);
+		pMsgDlg->DelayClose(3000);
+	};
+
+	SERVO::CRecipeList* pRecipeList = pEq->getRecipeList(0);
+	FillRecipeListToListCtrl(pRecipeList);
+	CloseHandle(hEvent);
+
+
+	return 0;
+}
diff --git a/SourceCode/Bond/Servo/PageRecipe.h b/SourceCode/Bond/Servo/PageRecipe.h
index 6833e3b..842082e 100644
--- a/SourceCode/Bond/Servo/PageRecipe.h
+++ b/SourceCode/Bond/Servo/PageRecipe.h
@@ -2,6 +2,8 @@
 #include "afxdialogex.h"
 #include "RecipeManager.h"
 #include "ListCtrlEx.h"
+#include "MsgDlg.h"
+
 
 // CPageRecipe 瀵硅瘽妗�
 
@@ -13,6 +15,10 @@
 	CPageRecipe(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
 	virtual ~CPageRecipe();
 
+public:
+	static UINT SyncThreadFunction(LPVOID lpvData);
+	UINT SyncThreadFunctionInner(CMsgDlg* pMsgDlg);
+
 private:
 	void InitListCtrlHeaderForMaster();
 	void InitListCtrlHeaderForDevice();
diff --git a/SourceCode/Bond/Servo/RecipeManager.h b/SourceCode/Bond/Servo/RecipeManager.h
index b27b026..41d8f02 100644
--- a/SourceCode/Bond/Servo/RecipeManager.h
+++ b/SourceCode/Bond/Servo/RecipeManager.h
@@ -6,6 +6,8 @@
 #include <mutex>
 #include <unordered_map>
 #include "Database.h"
+#include "CParam.h"
+
 
 // 单个设备配方映射信息
 struct DeviceRecipe {
@@ -21,6 +23,23 @@
     std::string strDescription;  // 配方描述
     std::string strCreateTime;   // 创建时间
     std::vector<DeviceRecipe> vecDeviceList;  // 关联的设备信息列表
+    std::vector<CParam*> m_params;			// 出站时记录参数
+    void RecipeInfo::addIntParam(const char* pszName, const char* pszId, const char* pszUnit, int value)
+    {
+        CParam* pParam = new CParam(pszName, pszId, pszUnit, value);
+        m_params.push_back(pParam);
+    }
+
+    void RecipeInfo::addDoubleParam(const char* pszName, const char* pszId, const char* pszUnit, double value)
+    {
+        CParam* pParam = new CParam(pszName, pszId, pszUnit, value);
+        m_params.push_back(pParam);
+    }
+
+    std::vector<CParam*>& RecipeInfo::getParams()
+    {
+        return m_params;
+    }
 };
 
 using RecipeMap = std::unordered_map<std::string, RecipeInfo>; // 按 PPID 映射的配方表
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index ec95643..a4e27f1 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -214,6 +214,7 @@
     <ClInclude Include="CPageLinkSignal.h" />
     <ClInclude Include="CPageReport.h" />
     <ClInclude Include="CPageVarialbles.h" />
+    <ClInclude Include="CParam.h" />
     <ClInclude Include="CReport.h" />
     <ClInclude Include="CRobotCmdContainerDlg.h" />
     <ClInclude Include="CRobotCmdTestDlg.h" />
@@ -368,6 +369,7 @@
     <ClCompile Include="CPageLinkSignal.cpp" />
     <ClCompile Include="CPageReport.cpp" />
     <ClCompile Include="CPageVarialbles.cpp" />
+    <ClCompile Include="CParam.cpp" />
     <ClCompile Include="CReport.cpp" />
     <ClCompile Include="CRobotCmdContainerDlg.cpp" />
     <ClCompile Include="CRobotCmdTestDlg.cpp" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index 1d90814..6ef9bf8 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -180,6 +180,7 @@
     <ClCompile Include="CControlJob.cpp" />
     <ClCompile Include="CExpandableListCtrl.cpp" />
     <ClCompile Include="CControlJobDlg.cpp" />
+    <ClCompile Include="CParam.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="AlarmManager.h" />
@@ -366,6 +367,7 @@
     <ClInclude Include="SerializeUtil.h" />
     <ClInclude Include="CExpandableListCtrl.h" />
     <ClInclude Include="CControlJobDlg.h" />
+    <ClInclude Include="CParam.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Servo.rc" />

--
Gitblit v1.9.3