From 155cb7fe0dcb564729c6aecdb65815f3f0ed24e2 Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期二, 13 一月 2026 11:28:26 +0800
Subject: [PATCH] 1.ECID, DVID的查询和实现;

---
 SourceCode/Bond/Servo/HsmsPassive.cpp |  234 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 200 insertions(+), 34 deletions(-)

diff --git a/SourceCode/Bond/Servo/HsmsPassive.cpp b/SourceCode/Bond/Servo/HsmsPassive.cpp
index 91f7254..df2aaeb 100644
--- a/SourceCode/Bond/Servo/HsmsPassive.cpp
+++ b/SourceCode/Bond/Servo/HsmsPassive.cpp
@@ -107,8 +107,6 @@
 	m_listener.onEQOffLine = nullptr;
 	m_listener.onEQOnLine = nullptr;
 	m_listener.onCommand = nullptr;
-	m_listener.onEQConstantRequest = nullptr;
-	m_listener.onEQConstantSend = nullptr;
 	m_pActiveAction = nullptr;
 	InitializeCriticalSection(&m_criticalSection);
 }
@@ -258,6 +256,9 @@
 	SERVO::CReport* pReport = new SERVO::CReport(RPTID, vids);
 	for (auto vid : vids) {
 		SERVO::CVariable* pVariable = getVariable(vid);
+		if (pVariable == nullptr) {
+			pVariable = getDataVariable(vid);
+		}
 		if (pVariable != nullptr) {
 			pReport->addVariable(pVariable);
 			LOGI("<CHsmsPassive>defineReport RPTID=%d", RPTID);
@@ -557,6 +558,95 @@
 	return 0;
 }
 
+int CHsmsPassive::loadEquipmentConstants(const char* pszFilepath)
+{
+	if (pszFilepath == NULL) return -1;
+	m_strEquipmentConstantFilepath = pszFilepath;
+	m_bEquipmentConstantUtf8 = false;
+	m_bEquipmentConstantUtf8Bom = false;
+
+	CFile file;
+	if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) {
+		return -1;
+	}
+	const ULONGLONG nLen = file.GetLength();
+	if (nLen == 0) {
+		return -1;
+	}
+	std::string buffer;
+	buffer.resize(static_cast<size_t>(nLen));
+	file.Read(buffer.data(), static_cast<UINT>(nLen));
+	file.Close();
+
+	if (hasUtf8Bom(buffer)) {
+		m_bEquipmentConstantUtf8 = true;
+		m_bEquipmentConstantUtf8Bom = true;
+		buffer = buffer.substr(3);
+	}
+	else if (isLikelyUtf8(buffer)) {
+		m_bEquipmentConstantUtf8 = true;
+	}
+	CStringW content = m_bEquipmentConstantUtf8 ? Utf8ToWide(buffer.c_str()) : AnsiToWide(buffer.c_str());
+	if (content.IsEmpty()) return -1;
+
+	std::wregex pattern(L"^\\d+,[^,]*,[^,]*,([^,]*),.*");
+	std::vector<EquipmentConstantEntry> constants;
+	CStringW strLine, strId, strName, strFormat, strRemark, strDefault;
+	std::wstringstream ss(content.GetString());
+	auto narrowFromW = [](const CStringW& s) -> std::string {
+		int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr);
+		if (need <= 0) return {};
+		std::string out(static_cast<size_t>(need - 1), '\0');
+		WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr);
+		return out;
+	};
+	std::wstring line;
+	while (std::getline(ss, line, L'\n')) {
+		strLine = line.c_str();
+		strLine.Trim();
+		if (strLine.IsEmpty()) continue;
+		if (strLine.Find(L"ECID") == 0) continue; // skip header
+		if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) {
+			continue;
+		}
+		int last = 0;
+		int idx = strLine.Find(L",", last);
+		if (idx < 0) continue;
+		strId = strLine.Left(idx);
+		last = idx + 1;
+
+		idx = strLine.Find(L",", last);
+		if (idx < 0) continue;
+		strName = strLine.Mid(last, idx - last);
+		last = idx + 1;
+
+		idx = strLine.Find(L",", last);
+		if (idx < 0) continue;
+		strFormat = strLine.Mid(last, idx - last);
+		last = idx + 1;
+
+		idx = strLine.Find(L",", last);
+		if (idx < 0) continue;
+		strRemark = strLine.Mid(last, idx - last);
+		last = idx + 1;
+
+		strDefault = strLine.Right(strLine.GetLength() - last);
+
+		EquipmentConstantEntry entry;
+		entry.id = _wtoi(strId);
+		entry.name = narrowFromW(strName);
+		entry.format = narrowFromW(strFormat);
+		entry.remark = narrowFromW(strRemark);
+		entry.value = narrowFromW(strDefault);
+		constants.push_back(entry);
+	}
+
+	if (!constants.empty()) {
+		m_equipmentConstants = std::move(constants);
+	}
+	return 0;
+}
+
 std::vector<SERVO::CVariable*>& CHsmsPassive::getVariables()
 {
 	return m_variabels;
@@ -714,6 +804,9 @@
 	if (auto v = getVariable(pszName)) {
 		v->setValue(value);
 	}
+	else if (auto dv = getDataVariable(pszName)) {
+		dv->setValue(value);
+	}
 	Unlock();
 }
 
@@ -723,6 +816,9 @@
 	if (auto v = getVariable(pszName)) {
 		v->setValue(value);
 	}
+	else if (auto dv = getDataVariable(pszName)) {
+		dv->setValue(value);
+	}
 	Unlock();
 }
 
@@ -731,6 +827,9 @@
 	Lock();
 	if (auto v = getVariable(pszName)) {
 		v->setValue(vars);
+	}
+	else if (auto dv = getDataVariable(pszName)) {
+		dv->setValue(vars);
 	}
 	Unlock();
 }
@@ -1006,6 +1105,9 @@
 		SERVO::CReport* pReport = new SERVO::CReport(_wtoi(strId), vids);
 		for (auto vid : vids) {
 			SERVO::CVariable* pVariable = getVariable(vid);
+			if (pVariable == nullptr) {
+				pVariable = getDataVariable(vid);
+			}
 			if (pVariable != nullptr) {
 				pReport->addVariable(pVariable);
 			}
@@ -1084,6 +1186,9 @@
 	SERVO::CReport* pReport = new SERVO::CReport(rptid, vids);
 	for (auto vid : vids) {
 		SERVO::CVariable* pVariable = getVariable((int)vid);
+		if (pVariable == nullptr) {
+			pVariable = getDataVariable((int)vid);
+		}
 		if (pVariable != nullptr) {
 			pReport->addVariable(pVariable);
 		}
@@ -1100,6 +1205,9 @@
 			SERVO::CReport* pReport = new SERVO::CReport(rptid, vids);
 			for (auto vid : vids) {
 				SERVO::CVariable* pVariable = getVariable((int)vid);
+				if (pVariable == nullptr) {
+					pVariable = getDataVariable((int)vid);
+				}
 				if (pVariable != nullptr) {
 					pReport->addVariable(pVariable);
 				}
@@ -2160,6 +2268,49 @@
 	return ER_NOERROR;
 }
 
+int CHsmsPassive::writeEquipmentConstantsToFile(const std::string& filepath)
+{
+	if (filepath.empty()) return -1;
+	CFile file;
+	if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone)) {
+		return -1;
+	}
+	const std::string headerAnsi = "ECID,EC Name,EC Format,EC Remark,Default Value\r\n";
+	if (m_bEquipmentConstantUtf8) {
+		if (m_bEquipmentConstantUtf8Bom) {
+			const BYTE bom[3] = { 0xEF, 0xBB, 0xBF };
+			file.Write(bom, 3);
+		}
+		CStringA header = AnsiToUtf8(headerAnsi);
+		file.Write(header.GetString(), header.GetLength());
+	}
+	else {
+		file.Write(headerAnsi.data(), (UINT)headerAnsi.size());
+	}
+	for (const auto& e : m_equipmentConstants) {
+		std::string line;
+		line.reserve(128);
+		line += std::to_string(e.id);
+		line.push_back(',');
+		line += e.name;
+		line.push_back(',');
+		line += e.format;
+		line.push_back(',');
+		line += e.remark;
+		line.push_back(',');
+		line += e.value;
+		line.append("\r\n");
+		if (m_bEquipmentConstantUtf8) {
+			CStringA out = AnsiToUtf8(line);
+			file.Write(out.GetString(), out.GetLength());
+		}
+		else {
+			file.Write(line.data(), (UINT)line.size());
+		}
+	}
+	file.Close();
+	return 0;
+}
 // S1F21/S1F22 - Data Variable Namelist
 int CHsmsPassive::replyDataVariableNamelistRequest(IMessage* pRecv)
 {
@@ -2318,32 +2469,42 @@
 	}
 
 
-	// 瑕佽幏鍙栫殑甯搁噺琛ㄨ〃
-	BOOL bCheckData = FALSE;
 	std::vector<EQConstant> eqcs;
 	{
 		ISECS2Item* pItem = pRecv->getBody();
-		int ecidSize = pItem->getSubItemSize();
+		const int ecidSize = pItem ? pItem->getSubItemSize() : 0;
 		for (int i = 0; i < ecidSize; i++) {
-			EQConstant eqc;
-			unsigned short id;
-			if (pItem->getSubItemU2(i, id)) {
+			EQConstant eqc{};
+			unsigned short id = 0;
+			if (pItem && pItem->getSubItemU2(i, id)) {
 				eqc.id = id;
 				eqcs.push_back(eqc);
 			}
 		}
 	}
-
-
-	// 浜ょ敱涓婂眰搴旂敤鏉ヨ幏鍙栨満鍣ㄥ父閲忓��
-	if (m_listener.onEQConstantRequest != nullptr) {
-		m_listener.onEQConstantRequest(this, eqcs);
+	// 绌哄垪琛ㄨ〃绀鸿姹傚叏閮� ECID
+	if (eqcs.empty()) {
+		for (const auto& e : m_equipmentConstants) {
+			EQConstant eqc{};
+			eqc.id = e.id;
+			strcpy_s(eqc.szValue, EQCONSTANT_VALUE_MAX, e.value.c_str());
+			eqcs.push_back(eqc);
+		}
+	} else {
+		for (auto& item : eqcs) {
+			auto it = std::find_if(m_equipmentConstants.begin(), m_equipmentConstants.end(),
+				[&](const EquipmentConstantEntry& e) { return e.id == item.id; });
+			if (it != m_equipmentConstants.end()) {
+				strcpy_s(item.szValue, EQCONSTANT_VALUE_MAX, it->value.c_str());
+			} else {
+				item.szValue[0] = '\0'; // unknown -> empty
+			}
+		}
 	}
-
 
 	// 鍥炲
 	IMessage* pMessage = NULL;
-	HSMS_Create1Message(pMessage, m_nSessionId, 1, 14, pRecv->getHeader()->systemBytes);
+	HSMS_Create1Message(pMessage, m_nSessionId, 2, 14, pRecv->getHeader()->systemBytes);
 	ASSERT(pMessage);
 	ISECS2Item* pItem = pMessage->getBody();
 	for (auto& item : eqcs) {
@@ -2367,33 +2528,38 @@
 	}
 
 
-	// 瑕佽缃殑甯搁噺琛ㄨ〃
-	BOOL bCheckData = FALSE;
+	// 瑕佽缃殑甯搁噺琛�
 	std::vector<EQConstant> eqcs;
 	{
 		ISECS2Item* pItem = pRecv->getBody();
-		int ecidSize = pItem->getSubItemSize();
+		int ecidSize = pItem ? pItem->getSubItemSize() : 0;
 		for (int i = 0; i < ecidSize; i++) {
-			ISECS2Item* pItemEqc = pItem->getSubItem(i);
-			if (pItemEqc != nullptr) {
-				EQConstant eqc;
-				unsigned short eqcid;
-				const char* pszValue;
-				if (pItemEqc->getSubItemU2(0, eqcid)
-					&& pItemEqc->getSubItemString(1, pszValue)) {
-					eqc.id = eqcid;
-					strcpy_s(eqc.szValue, EQCONSTANT_VALUE_MAX, pszValue);
-					eqcs.push_back(eqc);
-				}
+			ISECS2Item* pItemEqc = pItem ? pItem->getSubItem(i) : nullptr;
+			if (pItemEqc == nullptr) continue;
+			EQConstant eqc{};
+			unsigned short eqcid = 0;
+			const char* pszValue = nullptr;
+			if (pItemEqc->getSubItemU2(0, eqcid)
+				&& pItemEqc->getSubItemString(1, pszValue)) {
+				eqc.id = eqcid;
+				strcpy_s(eqc.szValue, EQCONSTANT_VALUE_MAX, pszValue);
+				eqcs.push_back(eqc);
 			}
 		}
 	}
 
-
-	// 浜ょ敱涓婂眰搴旂敤鏉ヤ繚瀛樺拰璁剧疆鏈哄櫒甯搁噺鍊�
-	std::vector<unsigned int> ecvs;
-	if (m_listener.onEQConstantSend != nullptr) {
-		m_listener.onEQConstantSend(this, eqcs);
+	// 鏇存柊鍐呭瓨琛ㄥ苟钀界洏
+	bool changed = false;
+	for (auto& item : eqcs) {
+		auto it = std::find_if(m_equipmentConstants.begin(), m_equipmentConstants.end(),
+			[&](const EquipmentConstantEntry& e) { return e.id == item.id; });
+		if (it != m_equipmentConstants.end()) {
+			it->value = item.szValue;
+			changed = true;
+		}
+	}
+	if (changed && !m_strEquipmentConstantFilepath.empty()) {
+		writeEquipmentConstantsToFile(m_strEquipmentConstantFilepath);
 	}
 
 

--
Gitblit v1.9.3