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.h | 18 +
SourceCode/Bond/EAPSimulator/CHsmsActive.h | 2
SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h | 2
SourceCode/Bond/Servo/HsmsPassive.cpp | 234 +++++++++++++++++++++++++----
SourceCode/Bond/EAPSimulator/EAPSimulator.rc | 26 +-
SourceCode/Bond/Servo/Model.cpp | 14 -
SourceCode/Bond/x64/Debug/VariableList.txt | 65 +++----
SourceCode/Bond/Servo/CPageGlassList.cpp | 2
SourceCode/Bond/EAPSimulator/CHsmsActive.cpp | 27 +++
SourceCode/Bond/EAPSimulator/Resource.h | 4
SourceCode/Bond/x64/Debug/DataVariableList.txt | 3
SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp | 59 +++++++
SourceCode/Bond/Servo/ClientListDlg.cpp | 2
13 files changed, 360 insertions(+), 98 deletions(-)
diff --git a/SourceCode/Bond/EAPSimulator/CHsmsActive.cpp b/SourceCode/Bond/EAPSimulator/CHsmsActive.cpp
index 6bd6013..a2539da 100644
--- a/SourceCode/Bond/EAPSimulator/CHsmsActive.cpp
+++ b/SourceCode/Bond/EAPSimulator/CHsmsActive.cpp
@@ -395,6 +395,33 @@
return 0;
}
+int CHsmsActive::hsmsEquipmentConstantRequest(const std::vector<unsigned short>& ecids)
+{
+ IMessage* pMessage = nullptr;
+ int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 2 | REPLY, 13, ++m_nSystemByte);
+ for (auto id : ecids) {
+ pMessage->getBody()->addU2Item(id, "ECID");
+ }
+ m_pActive->sendMessage(pMessage);
+ HSMS_Destroy1Message(pMessage);
+ return 0;
+}
+
+int CHsmsActive::hsmsEquipmentConstantSend(const std::vector<std::pair<unsigned short, std::string>>& ecidValues)
+{
+ IMessage* pMessage = nullptr;
+ int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 2 | REPLY, 15, ++m_nSystemByte);
+ ISECS2Item* pBody = pMessage->getBody();
+ for (const auto& kv : ecidValues) {
+ ISECS2Item* pEntry = pBody->addItem();
+ pEntry->addU2Item(kv.first, "ECID");
+ pEntry->addItem(kv.second.c_str(), "ECV");
+ }
+ m_pActive->sendMessage(pMessage);
+ HSMS_Destroy1Message(pMessage);
+ return 0;
+}
+
int CHsmsActive::hsmsQueryPPIDList()
{
IMessage* pMessage = nullptr;
diff --git a/SourceCode/Bond/EAPSimulator/CHsmsActive.h b/SourceCode/Bond/EAPSimulator/CHsmsActive.h
index 24d1016..9e8eb07 100644
--- a/SourceCode/Bond/EAPSimulator/CHsmsActive.h
+++ b/SourceCode/Bond/EAPSimulator/CHsmsActive.h
@@ -89,6 +89,8 @@
int hsmsQueryAllStatusVariables(); // S1F11
int hsmsQueryAllDataVariables(); // S1F21
int hsmsQueryAllCollectionEvents(); // S1F23
+ int hsmsEquipmentConstantRequest(const std::vector<unsigned short>& ecids); // S2F13
+ int hsmsEquipmentConstantSend(const std::vector<std::pair<unsigned short, std::string>>& ecidValues); // S2F15
// 鏌ヨPPID List
int hsmsQueryPPIDList();
diff --git a/SourceCode/Bond/EAPSimulator/EAPSimulator.rc b/SourceCode/Bond/EAPSimulator/EAPSimulator.rc
index fb5266e..92e768e 100644
--- a/SourceCode/Bond/EAPSimulator/EAPSimulator.rc
+++ b/SourceCode/Bond/EAPSimulator/EAPSimulator.rc
@@ -54,10 +54,10 @@
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
"LANGUAGE 4, 2\r\n"
- "#include ""res\\EAPSimulator.rc2"" // 闂�?Microsoft Visual C++ 缂傚倹鐗炵欢顐︽儍閸曨喚銈繝?\n"
- "#include ""l.CHS\\afxres.rc"" // 闁哄秴娲ら崳顖滅磼閸曨亝顐絓r\n"
+ "#include ""res\\EAPSimulator.rc2"" // 闂�?Microsoft Visual C++ 缂傚倸鍊归悧鐐垫椤愶附鍎嶉柛鏇ㄥ枤閵堫偅绻�?\n"
+ "#include ""l.CHS\\afxres.rc"" // 闂佸搫绉村ú銈夊闯椤栨粎纾奸柛鏇ㄤ簼椤�?\n"
"#if !defined(_AFXDLL)\r\n"
- "#include ""l.CHS\\afxribbon.rc"" // MFC 闁告梻鍠曢崗姗�宕犻崫鍕闁硅矇鍐ㄧ厬闁哄銈囥偒婵�?\n"
+ "#include ""l.CHS\\afxribbon.rc"" // MFC 闂佸憡姊婚崰鏇㈠礂濮椻偓瀹曠娀宕崟顒�顏梺纭呯焽閸愩劎鍘梺鍝勵棥閵堝洢鍋掑┑?\n"
"#endif\r\n"
"#endif\r\n"
"\0"
@@ -92,17 +92,17 @@
DEFPUSHBUTTON "纭畾",IDOK,113,41,50,14,WS_GROUP
END
-IDD_EAPSIMULATOR_DIALOG DIALOGEX 0, 0, 469, 292
+IDD_EAPSIMULATOR_DIALOG DIALOGEX 0, 0, 469, 319
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "EAPSimulator"
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
- DEFPUSHBUTTON "纭畾",IDOK,246,271,50,14,NOT WS_VISIBLE
- PUSHBUTTON "鍙栨秷",IDCANCEL,412,271,50,14,NOT WS_VISIBLE
- EDITTEXT IDC_EDIT_LOG,7,218,455,67,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL
- LTEXT "鏃ュ織锛�",IDC_STATIC,7,203,24,8
- GROUPBOX "鍔熻兘",IDC_STATIC,7,7,455,190
+ DEFPUSHBUTTON "纭畾",IDOK,246,298,50,14,NOT WS_VISIBLE
+ PUSHBUTTON "鍙栨秷",IDCANCEL,412,298,50,14,NOT WS_VISIBLE
+ EDITTEXT IDC_EDIT_LOG,7,245,455,67,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL
+ LTEXT "鏃ュ織锛�",IDC_STATIC,7,234,24,8
+ GROUPBOX "鍔熻兘",IDC_STATIC,7,7,455,223
LTEXT "IP:",IDC_STATIC,24,20,11,8
EDITTEXT IDC_EDIT_IP,39,17,94,14,ES_AUTOHSCROLL
LTEXT "Port:",IDC_STATIC,141,20,17,8
@@ -299,7 +299,7 @@
LEFTMARGIN, 7
RIGHTMARGIN, 462
TOPMARGIN, 7
- BOTTOMMARGIN, 285
+ BOTTOMMARGIN, 312
END
IDD_DIALOG_TERMINAL_DISPLAY, DIALOG
@@ -442,10 +442,10 @@
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE 4, 2
-#include "res\EAPSimulator.rc2" // 闈� Microsoft Visual C++ 缂栬緫鐨勮祫婧�
-#include "l.CHS\afxres.rc" // 鏍囧噯缁勪欢
+#include "res\EAPSimulator.rc2" // 闂�?Microsoft Visual C++ 缂傚倹鐗炵欢顐︽儍閸曨喚銈繝?
+#include "l.CHS\afxres.rc" // 闁哄秴娲ら崳顖滅磼閸曨亝顐�
#if !defined(_AFXDLL)
-#include "l.CHS\afxribbon.rc" // MFC 鍔熻兘鍖哄拰鎺у埗鏉¤祫婧�
+#include "l.CHS\afxribbon.rc" // MFC 闁告梻鍠曢崗姗�宕犻崫鍕闁硅矇鍐ㄧ厬闁哄銈囥偒婵�?
#endif
#endif
diff --git a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp
index 5ec0665..a52341f 100644
--- a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp
+++ b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp
@@ -107,6 +107,8 @@
ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_SVID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllSvid)
ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_DVID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllDvid)
ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_CEID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllCeid)
+ ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_ECID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllEcid)
+ ON_BN_CLICKED(IDC_BUTTON_SET_ECID, &CEAPSimulatorDlg::OnBnClickedButtonSetEcid)
ON_BN_CLICKED(IDC_BUTTON_QUERY_CURRENT_RECIPE, &CEAPSimulatorDlg::OnBnClickedButtonQueryCurrentRecipe)
ON_BN_CLICKED(IDC_BUTTON_PP_REQUEST, &CEAPSimulatorDlg::OnBnClickedButtonPpRequest)
END_MESSAGE_MAP()
@@ -290,6 +292,41 @@
if (hBtn != nullptr) {
::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE);
}
+ }
+ // S2F13 QueryAllECID
+ {
+ CRect rc(14 + 2 * (140 + 5), 192, 14 + 2 * (140 + 5) + 140, 192 + 14);
+ MapDialogRect(&rc);
+ HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S2F13_QueryAllECID"),
+ WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+ rc.left, rc.top, rc.Width(), rc.Height(),
+ m_hWnd, (HMENU)IDC_BUTTON_QUERY_ALL_ECID, AfxGetInstanceHandle(), nullptr);
+ if (hBtn != nullptr) {
+ ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE);
+ }
+ }
+ // ECID edit + send (S2F15)
+ {
+ CRect rcEcid(14, 192, 14 + 60, 192 + 14);
+ CRect rcEcv(14 + 60 + 4, 192, 14 + 60 + 4 + 60, 192 + 14);
+ MapDialogRect(&rcEcid);
+ MapDialogRect(&rcEcv);
+ HWND hEditEcid = ::CreateWindow(_T("EDIT"), _T(""), WS_CHILD | WS_VISIBLE | WS_BORDER,
+ rcEcid.left, rcEcid.top, rcEcid.Width(), rcEcid.Height(),
+ m_hWnd, (HMENU)IDC_EDIT_ECID, AfxGetInstanceHandle(), nullptr);
+ HWND hEditEcv = ::CreateWindow(_T("EDIT"), _T(""), WS_CHILD | WS_VISIBLE | WS_BORDER,
+ rcEcv.left, rcEcv.top, rcEcv.Width(), rcEcv.Height(),
+ m_hWnd, (HMENU)IDC_EDIT_ECV, AfxGetInstanceHandle(), nullptr);
+ if (hEditEcid) ::SendMessage(hEditEcid, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE);
+ if (hEditEcv) ::SendMessage(hEditEcv, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE);
+
+ CRect rcBtn(14 + 60 + 4 + 60 + 4, 192, 14 + 60 + 4 + 60 + 4 + 90, 192 + 14);
+ MapDialogRect(&rcBtn);
+ HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S2F15_SetECID"),
+ WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+ rcBtn.left, rcBtn.top, rcBtn.Width(), rcBtn.Height(),
+ m_hWnd, (HMENU)IDC_BUTTON_SET_ECID, AfxGetInstanceHandle(), nullptr);
+ if (hBtn) ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE);
}
// S1F3 CurrentRecipe (EQ specific) combo + button
{
@@ -675,6 +712,28 @@
theApp.m_model.m_pHsmsActive->hsmsQueryAllCollectionEvents();
}
+void CEAPSimulatorDlg::OnBnClickedButtonQueryAllEcid()
+{
+ // empty list => all ECID
+ std::vector<unsigned short> ecids;
+ ecids.push_back(2000);
+ theApp.m_model.m_pHsmsActive->hsmsEquipmentConstantRequest(ecids);
+}
+
+void CEAPSimulatorDlg::OnBnClickedButtonSetEcid()
+{
+ // simple demo: read ECID and value from edit boxes (reuse PPID edit)
+ CString sEcid, sVal;
+ GetDlgItemText(IDC_EDIT_ECID, sEcid);
+ GetDlgItemText(IDC_EDIT_ECV, sVal);
+ unsigned short id = static_cast<unsigned short>(_ttoi(sEcid));
+ std::string val = CT2A(sVal);
+ std::vector<std::pair<unsigned short, std::string>> kvs;
+ if (id != 0) {
+ kvs.push_back({ id, val });
+ theApp.m_model.m_pHsmsActive->hsmsEquipmentConstantSend(kvs);
+ }
+}
void CEAPSimulatorDlg::OnBnClickedButtonQueryCurrentRecipe()
{
CString sel;
diff --git a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h
index 2865c6b..d1e5537 100644
--- a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h
+++ b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h
@@ -73,6 +73,8 @@
afx_msg void OnBnClickedButtonQueryAllSvid();
afx_msg void OnBnClickedButtonQueryAllDvid();
afx_msg void OnBnClickedButtonQueryAllCeid();
+ afx_msg void OnBnClickedButtonQueryAllEcid();
+ afx_msg void OnBnClickedButtonSetEcid();
afx_msg void OnBnClickedButtonQueryCurrentRecipe();
afx_msg void OnBnClickedButtonPpRequest();
};
diff --git a/SourceCode/Bond/EAPSimulator/Resource.h b/SourceCode/Bond/EAPSimulator/Resource.h
index dee05ce..5c4789f 100644
--- a/SourceCode/Bond/EAPSimulator/Resource.h
+++ b/SourceCode/Bond/EAPSimulator/Resource.h
@@ -72,6 +72,10 @@
#define IDC_EDIT_PPID_REQ 1054
#define IDC_BUTTON_PP_REQUEST 1055
#define IDC_BUTTON_QUERY_ALL_DVID 1056
+#define IDC_BUTTON_QUERY_ALL_ECID 1057
+#define IDC_EDIT_ECID 1058
+#define IDC_EDIT_ECV 1059
+#define IDC_BUTTON_SET_ECID 1060
// Next default values for new objects
//
diff --git a/SourceCode/Bond/Servo/CPageGlassList.cpp b/SourceCode/Bond/Servo/CPageGlassList.cpp
index 68e2470..801a337 100644
--- a/SourceCode/Bond/Servo/CPageGlassList.cpp
+++ b/SourceCode/Bond/Servo/CPageGlassList.cpp
@@ -1364,7 +1364,7 @@
if (!row.pretty.empty()) {
CFile file;
if (file.Open(filePath, CFile::modeCreate | CFile::modeWrite)) {
- file.Write(row.pretty.c_str(), row.pretty.length());
+ file.Write(row.pretty.c_str(), (UINT)row.pretty.length());
file.Close();
CString strSuccess;
diff --git a/SourceCode/Bond/Servo/ClientListDlg.cpp b/SourceCode/Bond/Servo/ClientListDlg.cpp
index 500062e..1e8cd71 100644
--- a/SourceCode/Bond/Servo/ClientListDlg.cpp
+++ b/SourceCode/Bond/Servo/ClientListDlg.cpp
@@ -132,7 +132,7 @@
{
const ClientInfo& client = clients[i];
- int nItem = m_listClients.InsertItem(i, CString(client.ip.c_str()));
+ int nItem = m_listClients.InsertItem((int)i, CString(client.ip.c_str()));
m_listClients.SetItemText(nItem, 1, CString(std::to_string(client.port).c_str()));
m_listClients.SetItemText(nItem, 2, client.versionOk ? _T("姝e父") : _T("寮傚父"));
m_listClients.SetItemText(nItem, 3, CString(client.status.c_str()));
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);
}
diff --git a/SourceCode/Bond/Servo/HsmsPassive.h b/SourceCode/Bond/Servo/HsmsPassive.h
index 938a4ec..24815d7 100644
--- a/SourceCode/Bond/Servo/HsmsPassive.h
+++ b/SourceCode/Bond/Servo/HsmsPassive.h
@@ -79,7 +79,6 @@
typedef std::function<void(void* pFrom)> SECSEQOFFLINE;
-typedef std::function<void(void* pFrom, std::vector<EQConstant>&)> SECSEQCONSTANTREQUEST;
typedef std::function<void(void* pFrom, const char*, std::vector<CommandParameter>&)> SECSCommand;
typedef std::function<void(void* pFrom, SYSTEMTIME& time)> DATETIMESYNC;
typedef std::function<void(void* pFrom, bool bEnable, std::vector<unsigned int>& ids)> EDEVENTREPORT;
@@ -98,8 +97,6 @@
{
SECSEQOFFLINE onEQOffLine;
SECSEQOFFLINE onEQOnLine;
- SECSEQCONSTANTREQUEST onEQConstantRequest;
- SECSEQCONSTANTREQUEST onEQConstantSend;
SECSCommand onCommand;
DATETIMESYNC onDatetimeSync;
EDEVENTREPORT onEnableDisableEventReport;
@@ -149,6 +146,8 @@
int loadVarialbles(const char* pszFilepath);
// 浠庢枃浠朵腑鍔犺浇CDataVariable鍒楄〃
int loadDataVarialbles(const char* pszFilepath);
+ // 浠庢枃浠朵腑鍔犺浇Equipment Constant鍒楄〃
+ int loadEquipmentConstants(const char* pszFilepath);
// 鍙栧緱CVariable鍒楄〃
std::vector<SERVO::CVariable*>& getVariables();
@@ -276,6 +275,7 @@
std::vector<unsigned int> parseVidList(CString& strNums);
int writeVariablesToFile(const std::string& filepath);
int writeDataVariablesToFile(const std::string& filepath);
+ int writeEquipmentConstantsToFile(const std::string& filepath);
int writeReportsToFile(const std::string& filepath);
int writeCollectionEventsToFile(const std::string& filepath);
@@ -307,6 +307,9 @@
std::string m_strCollectionEventFilepath;
bool m_bCollectionUtf8{ false };
bool m_bCollectionUtf8Bom{ false };
+ std::string m_strEquipmentConstantFilepath;
+ bool m_bEquipmentConstantUtf8{ false };
+ bool m_bEquipmentConstantUtf8Bom{ false };
BOOL m_bCimWorking;
HANDLE m_hCimWorkEvent;
HANDLE m_hCimWorkThreadHandle;
@@ -319,6 +322,15 @@
std::vector<SERVO::CVariable*> m_variabels;
// CDataVariable vector
std::vector<SERVO::CDataVariable*> m_dataVariabels;
+ // Equipment constants
+ struct EquipmentConstantEntry {
+ unsigned int id{ 0 };
+ std::string name;
+ std::string format;
+ std::string remark;
+ std::string value;
+ };
+ std::vector<EquipmentConstantEntry> m_equipmentConstants;
// CReport vector
std::vector<SERVO::CReport*> m_reports;
diff --git a/SourceCode/Bond/Servo/Model.cpp b/SourceCode/Bond/Servo/Model.cpp
index 0c1c457..f571def 100644
--- a/SourceCode/Bond/Servo/Model.cpp
+++ b/SourceCode/Bond/Servo/Model.cpp
@@ -168,18 +168,6 @@
setControlState(ControlState::OnlineRemote);
}
};
- listener.onEQConstantRequest = [&](void* pFrom, std::vector<EQConstant>& eqcs) -> void {
- // 鍦ㄦ濉厖甯搁噺鍊硷紝鐩墠浠呮槸鍔�1鍚庤繑鍥�
- for (auto& item : eqcs) {
- sprintf_s(item.szValue, EQCONSTANT_VALUE_MAX, "Test%d", item.id + 1);
- }
- };
- listener.onEQConstantSend = [&](void* pFrom, std::vector<EQConstant>& eqcs) -> void {
- // 鍦ㄦ淇濆瓨鍜岃缃満鍣ㄥ父閲忓��
- for (auto& item : eqcs) {
- LOGI("onEQConstantRequest: %d, %s", item.id, item.szValue);
- }
- };
listener.onDatetimeSync = [&](void* pFrom, SYSTEMTIME& time) -> void {
LOGI("onDatetimeSync: %d%02d%02d%02d%02d%02d", time.wYear,
time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
@@ -313,6 +301,8 @@
m_hsmsPassive.loadVarialbles((LPTSTR)(LPCTSTR)strVarialbleFile);
strVarialbleFile.Format(_T("%s\\DataVariableList.txt"), (LPTSTR)(LPCTSTR)m_strWorkDir);
m_hsmsPassive.loadDataVarialbles((LPTSTR)(LPCTSTR)strVarialbleFile);
+ strVarialbleFile.Format(_T("%s\\EquipmentConstantList.txt"), (LPTSTR)(LPCTSTR)m_strWorkDir);
+ m_hsmsPassive.loadEquipmentConstants((LPTSTR)(LPCTSTR)strVarialbleFile);
setControlState(m_currentControlState);
refreshDerivedSVs();
m_hsmsPassive.init(this, "APP", 7000);
diff --git a/SourceCode/Bond/x64/Debug/DataVariableList.txt b/SourceCode/Bond/x64/Debug/DataVariableList.txt
index 0e29924..a874466 100644
--- a/SourceCode/Bond/x64/Debug/DataVariableList.txt
+++ b/SourceCode/Bond/x64/Debug/DataVariableList.txt
@@ -93,3 +93,6 @@
6701,Measurement_PD_Time,A20,Measurement PD: 鏃堕棿
6702,Measurement_PD_Value1,A20,Measurement PD: 娴嬮噺鍊�1
6703,Measurement_PD_Value2,A20,Measurement PD: 娴嬮噺鍊�2
+10200,SlotMap,U2,SlotMap(Scan)
+10201,SlotMapScan,U2,SlotMap(Scan)
+10202,SlotMapDownload,U2,SlotMap(Download)
diff --git a/SourceCode/Bond/x64/Debug/VariableList.txt b/SourceCode/Bond/x64/Debug/VariableList.txt
index 6ceaf95..71f7fbc 100644
--- a/SourceCode/Bond/x64/Debug/VariableList.txt
+++ b/SourceCode/Bond/x64/Debug/VariableList.txt
@@ -1,39 +1,36 @@
SVID,SV Name,SV Format,SV Remark
-100,PortTransferState,U1,0=OutOfService
-300,AccessMode,U1,1=Manual
-500,Clock,A50,
-600,CurrentControlState,U1,0:Offline:equipment
-601,PreviousControlState,U1,
-700,CurrentProcessState,U1,0:DOWN
-701,PreviousProcessState,U1,
-800,EFEMPPExecName,A20,
-801,EQPPExecName,A20,
-8100,Bonder1CurrentRecipe,A50,
-8101,Bonder2CurrentRecipe,A50,
-8102,VacuumBakeCurrentRecipe,A50,
-8103,BakeCoolingCurrentRecipe,A50,
-8104,MeasurementCurrentRecipe,A50,
-8105,EFEMCurrentRecipe,A50,
+100,PortTransferState,U1,0=OutOfService;1=ReadyToLoad/LoadRequest;2=Loaded;3=InUse/LoadComplete;4=ReadyToUnload/UnloadRequest;5=Empty/UnloadComplete;6=TransferBlocked
+300,AccessMode,U1,0=Auto;1=Manual
+500,Clock,A50,Current timestamp string
+600,CurrentControlState,U1,0=OfflineEquipment;1=OfflineAttempt;2=Online;3=OfflineHost;4=OnlineLocal;5=OnlineRemote
+601,PreviousControlState,U1,Previous control state (same code set as CurrentControlState)
+700,CurrentProcessState,U1,0=Ready;1=Processing;2=Complete;3=Error
+701,PreviousProcessState,U1,Previous process state (0=Ready;1=Processing;2=Complete;3=Error)
+800,EFEMPPExecName,A20,Current PPExec name from EFEM
+801,EQPPExecName,A20,Current PPExec name from equipment
+8100,Bonder1CurrentRecipe,A50,Current recipe for Bonder1
+8101,Bonder2CurrentRecipe,A50,Current recipe for Bonder2
+8102,VacuumBakeCurrentRecipe,A50,Current recipe for VacuumBake
+8103,BakeCoolingCurrentRecipe,A50,Current recipe for BakeCooling
+8104,MeasurementCurrentRecipe,A50,Current recipe for Measurement
+8105,EFEMCurrentRecipe,A50,Current recipe for EFEM
5001,CJobSpace,U1,CJ Space
5002,PJobSpace,U1,PJ Space
-5003,PJQueued,L,PJ Queued
-5004,PJStartID,A20,PJStartID
-5005,PJEndID,A20,PJEndID
-5006,PanelStartID,A20,PanelStartID
-5007,PanelEndID,A20,PanelEndID
-5008,CJStartID,A20,CJStartID
-5009,CJEndID,A20,CJEndID
-5010,UnloadReadyPortId,U1,Port ID
-5011,LoadReadyPortId,U1,Port ID
-5012,BlockedPortId,U1,Port ID
-5014,VCRPanelID,A20,Panel id, comes from reader
-5015,ReadyToReleasePortId,U1,Port ID
-5016,LoadPortNotAssocPortId,U1,Port ID
-5017,ProcessDataReportText,A50,EV_PROCESS_DATA_REPORT payload string (placeholder)
-5018,SubEqpName,A20,Equipment name for EV_SubEqpStart/EV_SubEqpEnd
-5019,SubEqpSlot,U1,Slot number for EV_SubEqpStart/EV_SubEqpEnd
+5003,PJQueued,L,PJ queued list (IDs)
+5004,PJStartID,A20,PJ start ID
+5005,PJEndID,A20,PJ end ID
+5006,PanelStartID,A20,Panel start ID
+5007,PanelEndID,A20,Panel end ID
+5008,CJStartID,A20,CJ start ID
+5009,CJEndID,A20,CJ end ID
+5010,UnloadReadyPortId,U1,Port ID (ReadyToUnload)
+5011,LoadReadyPortId,U1,Port ID (ReadyToLoad)
+5012,BlockedPortId,U1,Port ID (TransferBlocked)
+5014,VCRPanelID,A20,Panel ID from reader
+5015,ReadyToReleasePortId,U1,Port ID (ReadyToRelease)
+5016,LoadPortNotAssocPortId,U1,Port ID (LoadPortNotAssoc)
+5017,ProcessDataReportText,A50,EV_PROCESS_DATA_REPORT payload (placeholder)
+5018,SubEqpName,A20,Sub equipment name for SubEqp events
+5019,SubEqpSlot,U1,Slot number for SubEqp events
5020,PortStateChangePortId,U1,Port ID for PortStateChange
5021,PortState,U1,Port transfer/state code for PortStateChange
-10200,SlotMap,U2,SlotMap(Scan)
-10201,SlotMapScan,U2,SlotMap(Scan)
-10202,SlotMapDownload,U2,SlotMap(Download)
--
Gitblit v1.9.3