From 3f000671e15acd2de87c8588d7f09c0dc103bd7b Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期一, 08 九月 2025 13:56:23 +0800
Subject: [PATCH] 1.SVData获取和解释,待测试;

---
 SourceCode/Bond/Servo/Servo.vcxproj         |    2 
 SourceCode/Bond/Servo/CSVData.cpp           |   56 ++++
 SourceCode/Bond/Servo/CVacuumBake.cpp       |  144 ++++++++++++
 SourceCode/Bond/Servo/CMeasurement.h        |    4 
 SourceCode/Bond/Servo/CVacuumBake.h         |    4 
 SourceCode/Bond/Servo/CBakeCooling.cpp      |  157 +++++++++++++
 SourceCode/Bond/Servo/CMeasurement.cpp      |   51 ++++
 SourceCode/Bond/Servo/Servo.vcxproj.filters |    2 
 SourceCode/Bond/Servo/CBakeCooling.h        |    2 
 SourceCode/Bond/Servo/CEquipment.cpp        |   49 ++-
 SourceCode/Bond/Servo/CSVData.h             |   22 +
 SourceCode/Bond/Servo/CEFEM.cpp             |    7 
 SourceCode/Bond/Servo/CMaster.cpp           |   20 +
 SourceCode/Bond/Servo/CEquipment.h          |   14 +
 SourceCode/Bond/Servo/CBonder.h             |    2 
 SourceCode/Bond/Servo/CBonder.cpp           |  135 +++++++++++
 16 files changed, 648 insertions(+), 23 deletions(-)

diff --git a/SourceCode/Bond/Servo/CBakeCooling.cpp b/SourceCode/Bond/Servo/CBakeCooling.cpp
index dbfa816..dedf8a4 100644
--- a/SourceCode/Bond/Servo/CBakeCooling.cpp
+++ b/SourceCode/Bond/Servo/CBakeCooling.cpp
@@ -334,6 +334,26 @@
 			}
 		}
 
+		// FAC Data Report
+		addFacDataReportStep(0x12589, 0x94d, 1);
+		/*
+		{
+			CEqReadStep* pStep = new CEqReadStep(0x12589, 133 * 2,
+				[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
+					if (code == ROK && pszData != nullptr && size > 0) {
+						decodeFacDataReport((CStep*)pFrom, pszData, size);
+					}
+					return -1;
+				});
+			pStep->setName(STEP_EQ_FAC_DATA_REPORT);
+			pStep->setProp("Port", (void*)1);
+			pStep->setWriteSignalDev(0x94d);
+			if (addStep(STEP_ID_FAC_DATA_REPORT, pStep) != 0) {
+				delete pStep;
+			}
+		}
+		*/
+
 		// process start/end report
 		{
 			CEqReadStep* pStep = new CEqReadStep(0x11D3F, 13 * 2,
@@ -465,4 +485,141 @@
 		return (int)params.size();
 	}
 
+	int CBakeCooling::parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& params)
+	{
+		return parsingParams(pszData, size, params);
+	}
+
+	int CBakeCooling::parsingSVData(const char* pszData, size_t size, std::vector<CParam>& params)
+	{
+		/*
+		1	A烘烤工艺运行步骤	1Word	123456
+		2	A烘烤温控表1当前值	2Word	12345.6
+		3	A烘烤温控表2当前值	2Word	12345.6
+		4	A烘烤温控表4当前值	2Word	12345.6
+		5	A烘烤温控表5当前值	2Word	12345.6
+		6	A烘烤温控表6当前值	2Word	12345.6
+		7	A烘烤温控表7当前值	2Word	12345.6
+		8	A烘烤剩余时间	1Word	1234.56
+		9	A冷却工艺运行步骤	1Word	123456
+		10	A腔冷却剩余时间	1Word	1234.56
+		11	B烘烤工艺运行步骤	1Word	123456
+		12	B烘烤温控表1当前值	2Word	12345.6
+		13	B烘烤温控表2当前值	2Word	12345.6
+		14	B烘烤温控表4当前值	2Word	12345.6
+		15	B烘烤温控表5当前值	2Word	12345.6
+		16	B烘烤温控表6当前值	2Word	12345.6
+		17	B烘烤温控表7当前值	2Word	12345.6
+		18	B烘烤剩余时间	1Word	1234.56
+		19	B冷却工艺运行步骤	1Word	123456
+		20	B腔冷却剩余时间	1Word	1234.56
+		*/
+
+		ASSERT(pszData);
+		if (size < 125) return 0;
+		int i = 0, v;
+
+
+		// 1.A烘烤工艺运行步骤
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("A烘烤工艺运行步骤", "", this->getName().c_str(), v));
+		i += 2;
+
+		// 2.A烘烤温控表1当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A烘烤温控表1当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 3.A烘烤温控表2当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A烘烤温控表2当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 4.A烘烤温控表4当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A烘烤温控表4当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 5.A烘烤温控表5当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A烘烤温控表5当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 6.A烘烤温控表6当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A烘烤温控表6当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 7.A烘烤温控表7当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A烘烤温控表7当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 8.A烘烤剩余时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("A烘烤剩余时间", "", this->getName().c_str(), v * 0.01f));
+		i += 2;
+
+		// 9.A冷却工艺运行步骤
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("A冷却工艺运行步骤", "", this->getName().c_str(), v));
+		i += 2;
+
+		// 10.A腔冷却剩余时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("A腔冷却剩余时间", "", this->getName().c_str(), v * 0.01f));
+		i += 2;
+
+		// 11.B烘烤工艺运行步骤
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("B烘烤工艺运行步骤", "", this->getName().c_str(), v));
+		i += 2;
+
+		// 12.B烘烤温控表1当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B烘烤温控表1当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 13.B烘烤温控表2当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B烘烤温控表2当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 14.B烘烤温控表4当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B烘烤温控表4当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 15.B烘烤温控表5当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B烘烤温控表5当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 16.B烘烤温控表6当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B烘烤温控表6当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 17.B烘烤温控表7当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B烘烤温控表7当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 18.B烘烤剩余时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("B烘烤剩余时间", "", this->getName().c_str(), v * 0.01f));
+		i += 2;
+
+		// 19.B冷却工艺运行步骤
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("B冷却工艺运行步骤", "", this->getName().c_str(), v));
+		i += 2;
+
+		// 20.B腔冷却剩余时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("B腔冷却剩余时间", "", this->getName().c_str(), v * 0.01f));
+		i += 2;
+
+		return (int)params.size();
+	}
 }
diff --git a/SourceCode/Bond/Servo/CBakeCooling.h b/SourceCode/Bond/Servo/CBakeCooling.h
index 2cb07d6..3fcecfe 100644
--- a/SourceCode/Bond/Servo/CBakeCooling.h
+++ b/SourceCode/Bond/Servo/CBakeCooling.h
@@ -25,6 +25,8 @@
         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);
+        virtual int parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& parsms);
+        virtual int parsingSVData(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 c86ca7d..38d1d36 100644
--- a/SourceCode/Bond/Servo/CBonder.cpp
+++ b/SourceCode/Bond/Servo/CBonder.cpp
@@ -157,7 +157,6 @@
 			}
 		}
 
-
 		{
 			CEqDateTimeSetCmdStep* pStep = new CEqDateTimeSetCmdStep();
 			pStep->setName(STEP_DATETIME_SET_CMD);
@@ -266,6 +265,7 @@
 				}
 			}
 		}
+
 		{
 			// Sent Out Job Report Downstream #1~9
 			char szBuffer[256];
@@ -350,9 +350,12 @@
 			}
 		}
 
+		// FAC Data Report
+		addFacDataReportStep(m_nIndex == 0 ? 0xA589 : 0xE589,
+			m_nIndex == 0 ? 0x34d : 0x64d, 1);
+		/*
 		{
-			// FAC Data Report
-			CEqReadStep* pStep = new CEqReadStep(m_nIndex == 0 ? 0xA60E : 0xE60E, 108 * 2,
+			CEqReadStep* pStep = new CEqReadStep(m_nIndex == 0 ? 0xA589 : 0xE589, 133 * 2,
 				[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
 					if (code == ROK && pszData != nullptr && size > 0) {
 						decodeFacDataReport((CStep*)pFrom, pszData, size);
@@ -366,6 +369,7 @@
 				delete pStep;
 			}
 		}
+		*/
 
 		// process start/end report
 		{
@@ -642,4 +646,129 @@
 
 		return (int)params.size();
 	}
+
+	int CBonder::parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& params)
+	{
+		return parsingParams(pszData, size, params);
+	}
+
+	int CBonder::parsingSVData(const char* pszData, size_t size, std::vector<CParam>& params)
+	{
+		/*
+		1	工艺运行步骤	1Word	123456
+			2	气囊压力当前	2Word	12345.6
+			3	上腔压力合计	1Word	1234.56
+			4	管道真空规值	FLOAT	123.456
+			5	腔体真空规值	FLOAT	123.456
+			6	上腔温度1	1Word	12345.6
+			7	上腔温度2	1Word	12345.6
+			8	上腔温度3	1Word	12345.6
+			9	上腔温度4	1Word	12345.6
+			10	上腔温度5	1Word	12345.6
+			11	上腔温度6	1Word	12345.6
+			12	下腔温度1	1Word	12345.6
+			13	下腔温度2	1Word	12345.6
+			14	下腔温度3	1Word	12345.6
+			15	下腔温度4	1Word	12345.6
+			16	下腔温度5	1Word	12345.6
+			17	下腔温度6	1Word	12345.6
+			18	压合剩余时间	1Word	1234.56
+*/
+
+		ASSERT(pszData);
+		if (size < 125) return 0;
+		int i = 0, v;
+
+
+		// 1.工艺运行步骤
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("工艺运行步骤", "", this->getName().c_str(), v));
+		i += 2;
+
+		// 2.气囊压力当前
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("气囊压力当前", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 3.上腔压力合计
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("上腔压力合计", "", this->getName().c_str(), v * 0.01f));
+		i += 2;
+
+		// 4.管道真空规值
+		params.push_back(CParam("管道真空规值", "", this->getName().c_str(), (double)toFloat(&pszData[i])));
+		i += 4;
+
+		// 5.腔体真空规值
+		params.push_back(CParam("腔体真空规值", "", this->getName().c_str(), (double)toFloat(&pszData[i])));
+		i += 4;
+
+		// 6.上腔温度1
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("上腔温度1", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 7.上腔温度2
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("上腔温度2", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 8.上腔温度3
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("上腔温度3", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 9.上腔温度4
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("上腔温度4", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 10.上腔温度5
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("上腔温度5", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 11.上腔温度6
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("上腔温度6", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 12.下腔温度1
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("下腔温度1", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 13.下腔温度2
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("下腔温度2", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 14.下腔温度3
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("下腔温度3", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 15.下腔温度4
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("下腔温度4", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 16.下腔温度5
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("下腔温度5", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 17.下腔温度6
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("下腔温度6", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 18.压合剩余时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("压合剩余时间", "", this->getName().c_str(), v * 0.01f));
+		i += 2;
+
+		return (int)params.size();
+	}
+
 }
diff --git a/SourceCode/Bond/Servo/CBonder.h b/SourceCode/Bond/Servo/CBonder.h
index 714b949..b8a9f08 100644
--- a/SourceCode/Bond/Servo/CBonder.h
+++ b/SourceCode/Bond/Servo/CBonder.h
@@ -25,6 +25,8 @@
         virtual int onProcessStateChanged(PROCESS_STATE state);
         virtual int getIndexerOperationModeBaseValue();
         virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms);
+        virtual int parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& parsms);
+        virtual int parsingSVData(const char* pszData, size_t size, std::vector<CParam>& parsms);
 
     public:
         void setIndex(unsigned int index);
diff --git a/SourceCode/Bond/Servo/CEFEM.cpp b/SourceCode/Bond/Servo/CEFEM.cpp
index 39df4b4..fae20a5 100644
--- a/SourceCode/Bond/Servo/CEFEM.cpp
+++ b/SourceCode/Bond/Servo/CEFEM.cpp
@@ -697,9 +697,11 @@
 			}
 		}
 
+		// FAC Data Report
+		addFacDataReportStep(0x6589, 0x04d, 1);
+		/*
 		{
-			// FAC Data Report
-			CEqReadStep* pStep = new CEqReadStep(0x6301, 108 * 2,
+			CEqReadStep* pStep = new CEqReadStep(0x6589, 133 * 2,
 				[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
 					if (code == ROK && pszData != nullptr && size > 0) {
 						decodeFacDataReport((CStep*)pFrom, pszData, size);
@@ -713,6 +715,7 @@
 				delete pStep;
 			}
 		}
+		*/
 
 		{
 			// JOB Data Request
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index ab62475..e9eee92 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -490,6 +490,9 @@
 		// process data report
 		CHECK_READ_STEP_SIGNAL(STEP_ID_PROCESS_DATA_REPORT, pszData, size);
 
+		// FAC Data report
+		CHECK_READ_STEP_SIGNAL(STEP_ID_FAC_DATA_REPORT, pszData, size);
+
 		// 配方改变
 		CHECK_READ_STEP_SIGNAL(STEP_ID_CURRENT_RECIPE_CHANGE_REPORT, pszData, size);
 		
@@ -1773,21 +1776,14 @@
 
 	int CEquipment::decodeFacDataReport(CStep* pStep, const char* pszData, size_t size)
 	{
-		int index = 0;
-		std::string strSvTimeRecord, strSvData;
-		CToolUnits::convertString(&pszData[index], 8 * 2, strSvTimeRecord);
-		index += 128 * 2;
-		CToolUnits::convertString(&pszData[index], 100 * 2, strSvData);
-		index += 256 * 2;
+		CSVData svData;
+		int nRet = svData.unserialize(&pszData[0], (int)size);
+		if (nRet < 0) return nRet;
+		m_svDatas.push_back(svData);
 
-
-		// 缓存Attribute,用于调试时显示信息
-		unsigned int weight = 201;
-		pStep->addAttribute(new CAttribute("SV Time Record",
-			strSvTimeRecord.c_str(), "", weight++));
-		pStep->addAttribute(new CAttribute("SV Data",
-			strSvData.c_str(), "", weight++));
-
+		if (m_listener.onSVDataReport != nullptr) {
+			m_listener.onSVDataReport(this, &svData);
+		}
 
 		return 0;
 	}
@@ -1861,6 +1857,9 @@
 
 
 		if (m_processState != PROCESS_STATE::Processing) {
+			Lock();
+			m_svDatas.clear();
+			Unlock();
 			setProcessState(PROCESS_STATE::Processing);
 		}
 
@@ -2153,4 +2152,26 @@
 
 		return 0; 
 	};
+
+	void CEquipment::addFacDataReportStep(int dataDev, int writeSignalDev, int port)
+	{
+		CEqReadStep* pStep = new CEqReadStep(dataDev, 133 * 2,
+			[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
+				if (code == ROK && pszData != nullptr && size > 0) {
+					decodeFacDataReport((CStep*)pFrom, pszData, size);
+				}
+				return -1;
+			});
+		pStep->setName(STEP_EQ_FAC_DATA_REPORT);
+		pStep->setProp("Port", (void*)port);
+		pStep->setWriteSignalDev(writeSignalDev);
+		if (addStep(STEP_ID_FAC_DATA_REPORT, pStep) != 0) {
+			delete pStep;
+		}
+	}
+
+	std::vector<SERVO::CSVData>& CEquipment::getSVDatas()
+	{
+		return m_svDatas;
+	}
 }
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/CEquipment.h b/SourceCode/Bond/Servo/CEquipment.h
index 635c7a8..ffb7ea9 100644
--- a/SourceCode/Bond/Servo/CEquipment.h
+++ b/SourceCode/Bond/Servo/CEquipment.h
@@ -36,6 +36,7 @@
 #include "CPortStatusReport.h"
 #include "CSlot.h"
 #include "CParam.h"
+#include "CSVData.h"
 
 
 namespace SERVO {
@@ -57,6 +58,7 @@
 	typedef std::function<void(void* pEiuipment, PROCESS_STATE state)> ONPROCESSSTATE;
 	typedef std::function<void(void* pEiuipment, short scanMap, short downMap)> ONMAPMISMATCH;
 	typedef std::function<void(void* pEiuipment, short status, __int64 data)> ONPORTSTATUSCHANGED;
+	
 	typedef struct _EquipmentListener
 	{
 		ONALIVE				onAlive;
@@ -69,7 +71,7 @@
 		ONPROCESSSTATE		onProcessStateChanged;
 		ONMAPMISMATCH		onMapMismatch;
 		ONPORTSTATUSCHANGED	onPortStatusChanged;
-
+		ONVCREVENTREPORT	onSVDataReport;
 	} EquipmentListener;
 
 
@@ -158,7 +160,7 @@
 		int setDispatchingMode(DISPATCHING_MODE mode, ONWRITED onWritedBlock = nullptr);
 		int indexerOperationModeChange(IDNEXER_OPERATION_MODE mode, ONWRITEDRET onWritedRetBlock);
 		void printDebugString001();
-
+		std::vector<SERVO::CSVData>& getSVDatas();
 
 		// 请求主配方列表
 		// unitNo: 0:local; Others:unit No
@@ -173,6 +175,8 @@
 		// 解析配方参数列表
 		virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& params) { return 0;  };
 		virtual int parsingParams(const char* pszData, size_t size, std::string& strOut);
+		virtual int parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& params) { return 0; };
+		virtual int parsingSVData(const char* pszData, size_t size, std::vector<CParam>& params) { return 0; };
 
 		// 获取指定的Slot
 		CSlot* getSlot(int index);
@@ -264,6 +268,11 @@
 		float toFloat(const char* pszAddr);
 
 	protected:
+		// 部分优化/简化代码、暂实现部分,到时平铺开
+		void addFacDataReportStep(int dataDev, int writeSignalDev, int port);
+
+
+	protected:
 		BOOL m_bEnable;
 		EquipmentListener m_listener;
 		int m_nID;
@@ -296,6 +305,7 @@
 		CRecipesManager m_recipesManager;
 		CSlot m_slot[SLOT_MAX];
 		PROCESS_STATE m_processState;
+		std::vector<SERVO::CSVData> m_svDatas;
 
 	private:
 		CEquipment* m_pArm;
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 405eca3..425ac92 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -1552,6 +1552,26 @@
 				m_listener.onLoadPortStatusChanged(this, (CEquipment*)pEquipment, status, data);
 			}
 		};
+		listener.onSVDataReport = [&](void* pEquipment, void* pData) {
+			CSVData* pSVData = (CSVData*)pData;
+			auto rawData = pSVData->getSVRawData();
+			std::vector<CParam> params;
+			((CEquipment*)pEquipment)->parsingSVData((const char*)rawData.data(), rawData.size(), params);
+		
+			std::string strOut;
+			char szBuffer[256];
+			for (auto p : params) {
+				if (!strOut.empty()) strOut.append(",");
+				if (p.getValueType() == PVT_INT) {
+					sprintf_s(szBuffer, 256, "%s:%d", p.getName().c_str(), p.getIntValue());
+				}
+				else if (p.getValueType() == PVT_DOUBLE) {
+					sprintf_s(szBuffer, 256, "%s:%f", p.getName().c_str(), p.getDoubleValue());
+				}
+				strOut.append(szBuffer);
+			}
+			LOGI("<CMaster-%s>SVDataReport:%s", ((CEquipment*)pEquipment)->getName().c_str(), strOut.c_str());
+		};
 		pEquipment->setListener(listener);
 		pEquipment->setCcLink(&m_cclink);
 		m_listEquipment.push_back(pEquipment);
diff --git a/SourceCode/Bond/Servo/CMeasurement.cpp b/SourceCode/Bond/Servo/CMeasurement.cpp
index 0acf5ee..8357d01 100644
--- a/SourceCode/Bond/Servo/CMeasurement.cpp
+++ b/SourceCode/Bond/Servo/CMeasurement.cpp
@@ -334,6 +334,26 @@
 			}
 		}
 
+		// FAC Data Report
+		addFacDataReportStep(0x1a589, 0xf4d, 1);
+		/*
+		{
+			CEqReadStep* pStep = new CEqReadStep(0x1a589, 133 * 2,
+				[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
+					if (code == ROK && pszData != nullptr && size > 0) {
+						decodeFacDataReport((CStep*)pFrom, pszData, size);
+					}
+					return -1;
+				});
+			pStep->setName(STEP_EQ_FAC_DATA_REPORT);
+			pStep->setProp("Port", (void*)1);
+			pStep->setWriteSignalDev(0xf4d);
+			if (addStep(STEP_ID_FAC_DATA_REPORT, pStep) != 0) {
+				delete pStep;
+			}
+		}
+		*/
+
 		// process start/end report
 		{
 			CEqReadStep* pStep = new CEqReadStep(0x19D3F, 13 * 2,
@@ -437,4 +457,35 @@
 
 		return (int)params.size();
 	}
+
+	int CMeasurement::parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& params)
+	{
+		return parsingParams(pszData, size, params);
+	}
+
+	int CMeasurement::parsingSVData(const char* pszData, size_t size, std::vector<CParam>& params)
+	{
+		/*/
+		1	工艺运行步骤	1Word	123456
+			2	AOI检测速度	2Word	123.456
+		*/
+
+		ASSERT(pszData);
+		if (size < 125) return 0;
+		int i = 0, v;
+
+
+		// 1.工艺运行步骤
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("工艺运行步骤", "", this->getName().c_str(), v));
+		i += 2;
+
+		// 2.检测速度
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A腔温控表1当前值", "", this->getName().c_str(), v * 0.001f));
+		i += 4;
+
+		return (int)params.size();
+	}
+
 }
diff --git a/SourceCode/Bond/Servo/CMeasurement.h b/SourceCode/Bond/Servo/CMeasurement.h
index 9a040ee..5ac68c9 100644
--- a/SourceCode/Bond/Servo/CMeasurement.h
+++ b/SourceCode/Bond/Servo/CMeasurement.h
@@ -23,6 +23,8 @@
         virtual int recvIntent(CPin* pPin, CIntent* pIntent);
         virtual int getIndexerOperationModeBaseValue();
         virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms);
-	};
+        virtual int parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& parsms);
+        virtual int parsingSVData(const char* pszData, size_t size, std::vector<CParam>& parsms);
+    };
 }
 
diff --git a/SourceCode/Bond/Servo/CSVData.cpp b/SourceCode/Bond/Servo/CSVData.cpp
new file mode 100644
index 0000000..22ee583
--- /dev/null
+++ b/SourceCode/Bond/Servo/CSVData.cpp
@@ -0,0 +1,56 @@
+#include "stdafx.h"
+#include "CSVData.h"
+#include "ToolUnits.h"
+
+
+namespace SERVO {
+	CSVData::CSVData()
+	{
+
+	}
+
+	CSVData::~CSVData()
+	{
+
+	}
+
+	std::string& CSVData::getTime()
+	{
+		return m_strTime;
+	}
+
+	std::vector<uint8_t>& CSVData::getSVRawData()
+	{
+		return m_svRawData;
+	}
+
+	int CSVData::serialize(char* pszBuffer, int nBufferSize)
+	{
+		if (nBufferSize < 133) return -1;
+
+		int index = 0;
+		CToolUnits::convertString(&pszBuffer[index], 8, m_strTime);
+		index += 8;
+
+		memcpy(&pszBuffer[index], m_svRawData.data(), 125);
+		index += 125;
+
+		return 133;
+	}
+
+	int CSVData::unserialize(const char* pszBuffer, int nBufferSize)
+	{
+		if (nBufferSize < 133) return -1;
+
+		int index = 0;
+		CSVData svData;
+		CToolUnits::convertString(&pszBuffer[index], 8, m_strTime);
+		index += 8;
+
+		m_svRawData.clear();
+		m_svRawData.insert(m_svRawData.end(), (uint8_t*)(pszBuffer), (uint8_t*)(pszBuffer)+125);
+		index += 125;
+
+		return 133;
+	}
+}
diff --git a/SourceCode/Bond/Servo/CSVData.h b/SourceCode/Bond/Servo/CSVData.h
new file mode 100644
index 0000000..c3efdc5
--- /dev/null
+++ b/SourceCode/Bond/Servo/CSVData.h
@@ -0,0 +1,22 @@
+#pragma once
+
+
+namespace SERVO {
+	class CSVData
+	{
+	public:
+		CSVData();
+		virtual ~CSVData();
+
+	public:
+		std::string& getTime();
+		std::vector<uint8_t>& getSVRawData();
+		int serialize(char* pszBuffer, int nBufferSize);
+		int unserialize(const char* pszBuffer, int nBufferSize);
+
+	private:
+		std::string m_strTime;
+		std::vector<uint8_t> m_svRawData;
+	};
+}
+
diff --git a/SourceCode/Bond/Servo/CVacuumBake.cpp b/SourceCode/Bond/Servo/CVacuumBake.cpp
index 18e298b..ea3bf70 100644
--- a/SourceCode/Bond/Servo/CVacuumBake.cpp
+++ b/SourceCode/Bond/Servo/CVacuumBake.cpp
@@ -334,6 +334,26 @@
 			}
 		}
 
+		// FAC Data Report
+		addFacDataReportStep(0x16589, 0xc4d, 1);
+		/*
+		{
+			CEqReadStep* pStep = new CEqReadStep(0x16589, 133 * 2,
+				[&](void* pFrom, int code, const char* pszData, size_t size) -> int {
+					if (code == ROK && pszData != nullptr && size > 0) {
+						decodeFacDataReport((CStep*)pFrom, pszData, size);
+					}
+					return -1;
+				});
+			pStep->setName(STEP_EQ_FAC_DATA_REPORT);
+			pStep->setProp("Port", (void*)1);
+			pStep->setWriteSignalDev(0xc4d);
+			if (addStep(STEP_ID_FAC_DATA_REPORT, pStep) != 0) {
+				delete pStep;
+			}
+		}
+		*/
+
 		// process start/end report
 		{
 			CEqReadStep* pStep = new CEqReadStep(0x15D3F, 13 * 2,
@@ -459,4 +479,128 @@
 
 		return (int)params.size();
 	}
+
+	int CVacuumBake::parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& params)
+	{
+		return parsingParams(pszData, size, params);
+	}
+
+	int CVacuumBake::parsingSVData(const char* pszData, size_t size, std::vector<CParam>& params)
+	{
+		/*
+		1	A腔工艺运行步骤	1Word	123456
+			2	A腔体真空规值	FLOAT	123.456
+			3	A腔温控表1当前值	2Word	12345.6
+			4	A腔温控表2当前值	2Word	12345.6
+			5	A腔温控表4当前值	2Word	12345.6
+			6	A腔温控表5当前值	2Word	12345.6
+			7	A腔温控表6当前值	2Word	12345.6
+			8	A腔温控表7当前值	2Word	12345.6
+			9	A腔烘烤剩余时间	1Word	12345.6
+			10	B腔工艺运行步骤	1Word	123456
+			11	B腔体真空规值	FLOBT	123.456
+			12	B腔温控表1当前值	2Word	12345.6
+			13	B腔温控表2当前值	2Word	12345.6
+			14	B腔温控表4当前值	2Word	12345.6
+			15	B腔温控表5当前值	2Word	12345.6
+			16	B腔温控表6当前值	2Word	12345.6
+			17	B腔温控表7当前值	2Word	12345.6
+			18	B腔烘烤剩余时间	1Word	12345.6
+	*/
+
+		ASSERT(pszData);
+		if (size < 125) return 0;
+		int i = 0, v;
+
+
+		// 1.A腔工艺运行步骤
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("A腔工艺运行步骤", "", this->getName().c_str(), v));
+		i += 2;
+
+		// 2.A腔体真空规值
+		params.push_back(CParam("A腔体真空规值", "", this->getName().c_str(), (double)toFloat(&pszData[i])));
+		i += 4;
+
+		// 3.A腔温控表1当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A腔温控表1当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 4.A腔温控表2当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A腔温控表2当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 5.A腔温控表4当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A腔温控表4当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 6.A腔温控表5当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A腔温控表5当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 7.A腔温控表6当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A腔温控表6当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 8.A腔温控表7当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("A腔温控表7当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 9.A腔烘烤剩余时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("A腔烘烤剩余时间", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		// 10.B腔工艺运行步骤
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("B腔工艺运行步骤", "", this->getName().c_str(), v));
+		i += 2;
+
+		// 11.A腔体真空规值
+		params.push_back(CParam("B腔体真空规值", "", this->getName().c_str(), (double)toFloat(&pszData[i])));
+		i += 4;
+
+		// 12.B腔温控表1当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B腔温控表1当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 13.B腔温控表2当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B腔温控表2当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 14.B腔温控表4当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B腔温控表4当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 15.B腔温控表5当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B腔温控表5当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 16.B腔温控表6当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B腔温控表6当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 17.B腔温控表7当前值
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
+		params.push_back(CParam("B腔温控表7当前值", "", this->getName().c_str(), v * 0.1f));
+		i += 4;
+
+		// 18.B腔烘烤剩余时间
+		v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
+		params.push_back(CParam("B腔烘烤剩余时间", "", this->getName().c_str(), v * 0.1f));
+		i += 2;
+
+		return (int)params.size();
+	}
 }
diff --git a/SourceCode/Bond/Servo/CVacuumBake.h b/SourceCode/Bond/Servo/CVacuumBake.h
index 9a49637..9d751bb 100644
--- a/SourceCode/Bond/Servo/CVacuumBake.h
+++ b/SourceCode/Bond/Servo/CVacuumBake.h
@@ -23,6 +23,8 @@
         virtual int recvIntent(CPin* pPin, CIntent* pIntent);
         virtual int getIndexerOperationModeBaseValue();
         virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms);
-	};
+        virtual int parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& parsms);
+        virtual int parsingSVData(const char* pszData, size_t size, std::vector<CParam>& parsms);
+    };
 }
 
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index cee27dc..318e982 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -231,6 +231,7 @@
     <ClInclude Include="CPagePortStatus.h" />
     <ClInclude Include="CPortStatusReport.h" />
     <ClInclude Include="CRobotTaskDlg.h" />
+    <ClInclude Include="CSVData.h" />
     <ClInclude Include="CVariable.h" />
     <ClInclude Include="GlassJson.h" />
     <ClInclude Include="GridControl\CellRange.h" />
@@ -400,6 +401,7 @@
     <ClCompile Include="CPagePortStatus.cpp" />
     <ClCompile Include="CPortStatusReport.cpp" />
     <ClCompile Include="CRobotTaskDlg.cpp" />
+    <ClCompile Include="CSVData.cpp" />
     <ClCompile Include="CVariable.cpp" />
     <ClCompile Include="GlassJson.cpp" />
     <ClCompile Include="GridControl\GridCell.cpp" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index e8763fd..6048cc1 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -192,6 +192,7 @@
     <ClCompile Include="..\jsoncpp\lib_json\json_writer.cpp">
       <Filter>JsonCpp</Filter>
     </ClCompile>
+    <ClCompile Include="CSVData.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="AlarmManager.h" />
@@ -408,6 +409,7 @@
     <ClInclude Include="..\jsoncpp\lib_json\json_batchallocator.h">
       <Filter>JsonCpp</Filter>
     </ClInclude>
+    <ClInclude Include="CSVData.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Servo.rc" />

--
Gitblit v1.9.3